Ultralearning Software Development: A Successful Environment for Ultralearning Software Development

Part Two: A Successful Environment for Ultralearning Software Development

After reading about the ineffectiveness of formal classroom education in Ultralearning, I couldn’t help but reflect on an invited talk Nathaniel and I gave at the OOPSLA 2000: Educator’s Symposium. The talk was entitled “Apprenticeship in a Software Studio: An Old and New Model for Education,” in it, Nathaniel Talbott and I basically explained our 2.5-year experience. Nathaniel, at the time, was the post-apprentice, and I was the “Master Software Craftsman” who oversaw his learning and growth as we worked on custom software development projects. At the end of our talk, one of the formal educators said, “He’s going to ruin that poor kid.” I recently called Nathaniel to apologize for ruining him. He is a happy husband and father who has provided for many children. After 20+ years in the industry, in which he started two companies, including a successful start-up that was sold for tens of millions of dollars. He readily forgave me.

In addition… we have launched many highly effective and successful software development careers.

Not everyone has made it through with flying colors, and a few dropped out. We’ve gotten better at identifying success factors in applicants. But those who have completed our Academy have definitely learned deeply and in an accelerated fashion. Most have had great success in just about every measure one might have unless having “the college experience” or “earning a degree” is your measure of success. Note, however; we have had some Academy completers who joined after a college experience and one that earned two accelerated degrees after completing our Academy while working for us part-time (a B.S. in Computer Science and an M.S. in Data Science).

What we call “immersion” sections are similar to learning by simulation.

We give them all the same tools that our developers use but give them a project where no one gets hurt if they crash. We start with immersion/simulations guided by our experienced developers and slowly bring them into our real work, with the goal of going from Novice (what we call them until they complete our first two immersion sections), to Apprentice, to Resident, Sr. Resident, and eventually “Developer” and beyond.

So, where is the application of the principles of Ultralearning in our Software Craftsmanship Academy?

First Draw a Map

Ultralearning advises its adherents to draw a map of what they need to learn to achieve their goals. It warns that it won’t be perfect because they don’t know what they don’t know yet.

Since we’ve done this for a while, we have a pretty good handle on the basic concepts Academy participants will need to learn. We’ve drawn the initial map for them on the things they need to learn to become a successful software developer. It may not be perfect, but we are confident it is far better than what they might figure out on their own. It’s the 80/20 rule. We’ll hit the first 80 percent of what they need to know in just about every software project they’ll ever be involved in. The other 20 percent takes a lifetime.

We break the 80 percent into one-week chunks with progressively harder projects to cement the concepts they’ll be building upon and expose them to the next set of concepts. We tell them they are pretty much expected to have a working application at the end of each week, and in order to do that, they’ll have to apply a given set of concepts that we expose to them at the beginning of the week. This is a project that is bigger and different than anything they’ve done before (although relatively simple to an experienced developer).

However, we don’t just draw them a map of concepts with names they don’t understand. As expert guides, we lead them through their journey, giving them what they need at the moment. They can only see somewhat clearly to the horizon that is in front of them. When they get to the following horizon, the next section of the map becomes relevant. 

We point them in the right direction, and the next horizon is a week away. We leave them alone for a few hours to make progress in applying the concepts we’ve given them to the project at hand. We set them up to get to a point on their projects where they’ll hit a bump and will need a new concept to get over. We know it’s coming.

The concepts we give them fit the context of the problem they are facing, so they apply them right away and start getting comfortable with them. They see and feel how the concepts apply.

We check in and make sure they are applying them well, asking them to offer up a “sacrifice of code” that we put on the big screen for each to see as we offer constructive criticism on what they’ve done so far. There are no points marked off their test; just learning how to better apply the concepts. We ask if they have any questions about how to proceed.

They may have other questions, but there is a good chance they’ll be up against a problem that either: they addressed in a way that would bite them later, or it stopped them in their tracks because they smelled the danger and didn’t know how to avoid it. When that happens, we’re ready with the next concept, which usually takes just a few minutes to explain. They are already in the context where the concept is needed. Instead of explaining the context in an abstract way and hoping that they would someday see a concrete example and recognize it, we might explain that this is a concrete example of an abstract, but common, approach to something they’ll come up against again. 

If we told them everything they needed to know ahead of time, they’d be overwhelmed, and some concepts would slip their mind when they need them, even a few days later. They wouldn’t recognize the context where it should be used. Once they have felt the pain and felt how the concept relieves the pain, they rarely forget it. Contrast this with teaching a lot of concepts in a classroom setting and attempting to explain the context in which each would apply and giving them a test in which they have to repeat back the concept and context. If it was years until they ran into the context again, would they remember it? We introduce the most foundational and pervasive concepts early, building upon them and hammering them home over the following weeks. The projects they build in the first part of the immersion are somewhat toy projects (they actually work and can be used, but they are not necessarily very marketable). But, when they join our experienced developers on real projects within a few weeks, they’ll already know these concepts. 

Practice Before Theory?

I remember taking my Linear Algebra class as a sophomore in college. We learned about determinants. I struggled to get the concept. I didn’t know what it was for. Twenty years later, I tackled for the first time a project working with 3D graphics programming.  Someone pointed out the value of a determinant. All I remembered was the word and that it was taught in my Linear Algebra class. I had to relearn how to calculate it and learn for the first time how to apply it. That took a few minutes. Would it have taken any longer if I hadn’t ever taken that Linear Algebra class and instead was introduced first to 3D Graphics programming? I’ve seen people learn in a matter of weeks more of the relevant concepts about software development than I learned in my four-year computer science education at a top engineering school. And in a matter of months, our Academy participants have more experience actually programming and on more significant projects.

The only real academic prerequisite we have before the journey on our initial map is that they’ve already learned the basic fundamentals of programming (variables, conditionals, loops, etc.) and have applied them on some (presumably trivial) projects. Part of the application process includes an interactive assessment in which we present elementary problems and see how they handle answering them. (If they don’t have the background to answer the problem, we see how they might reason about their approach to solving the problem. For e.g., we give them a problem that COULD be solved through recursion and see if they “smell” the solution, whether they can actually write the code or not).

We also give them some pre-work to get familiar with the environment they’ll use when the Academy starts. The more solid they are on the fundamentals of programming and familiarity with the environment, the better, but as long as they have the prereqs before starting, they are ready to be immersed.

After they complete the first three months of our Academy, they have a bit more background to help them draw the next part of their own map. Maybe they want to focus on front-end development, or back-end development, or 3D graphics, or ???. They finish the immersion phase of the Academy with the foundation they’ll need for any of those with content for the bigger picture. For e.g., “front-end development” exists in the context of a broader software application, and they should understand where it fits and why everything should NOT be done on the “front-end.”


We tell them to minimize any outside distractions during the Academy. They’ll be putting in at least 40 and up to 60 or 80 hours per week focused on getting their projects done within the guidelines they are given.

Just like the example of people becoming proficient in a foreign language through a 3-month immersion, we want them to be immersed in becoming proficient software developers.

Beginning on day one, they have a problem to solve, and they have to solve a certain amount of it by the next day. No time for procrastination. You have a deadline to keep. They keep this pace during the duration of the immersion period. If they get stuck or don’t hit a goal in time, we work with them to diagnose why. Once we understand why they are stuck, we help them develop a solution and try again. 

The whole group has the same tasks to focus on. They all sit in the same room, all focused on the same problem, all with the same deadline. They have to stay focused on best practices, and we give them rules to follow to stay on track. All the problems they work through are designed to engrain good habits and to allow them to focus on the patterns they will need to know to accomplish just about anything. 

From the beginning, they use test-driven development. They must write a test for any code they are going to write; if they don’t write a test, they have to throw out their code. We are teaching them to become software developers of complex systems. Best practices allow you to solve complex business problems without the extra complexities, solving complex problems in a simple way. Once they understand and can implement best practices, they can apply them to complex situations. 

When you want to learn a new skill, there is so much to learn you don’t know what to focus on. Giving a bunch of theories at the beginning of a journey is an almost sure way to use the wrong theory in the wrong context. Since our goal is to teach people to be a producer of sustainable software, the core values of what needs to be pervasive to create sustainable software are what we focus on… not individual theories that only apply in certain situations. We explain the importance of Intention Revealing Names, and the mantras Red-Green-Refactor and Make it Run, Make it Right, Make it Fast (Enough). These are things that the best-experienced developers have learned are consistently important.

In contrast, years ago, I remember being at a client where they hired a young developer fresh out of college with a B.S. in Computer Science. At the end of a workday, he asked me to check out the work he’d been doing. He then showed me how he had built a binary tree collection because the application the client was building had been using linear searches, and they are “so inefficient.” Examining his work, I quickly recognized the unconventional naming conventions he was using that were not consistent with the rest of the system and made several attempts to pinpoint the particular performance problem he was asked to solve. He kept saying that they were using a linear search. I then asked if the typical collections of objects in this part of the application were particularly large, as in the thousands or tens of thousands. He said, “no, typically 5-10 objects.” At this point, all I could do was gently inform him that it would take a lot of work to convert those collections into the ones he created and how quickly the linear searches he was concerned about were already being done by the computer.

Although I am thankful for those who have studied search algorithms, and know a bit about them myself, teaching them without the context of application software development can easily lead an aspiring software craftsman down the wrong path. I typically share the above story in the context of teaching the “Make it Run, Make it Right, Make it Fast (enough)” mantra that will keep a young developer from wasting time optimizing something that takes the computer nanoseconds to accomplish. And when I see them actually doing something that might take the computer seconds or minutes to do, I point out the general types of things that actually contribute to most performance problems (which are almost never bad search algorithms). We discuss where to focus and what to do to get around them. We also point out the costs of premature optimization and why we don’t typically start there.

We give them what to focus on and create building blocks so they can go farther. We build an environment tailored to immersion and create a place where they can succeed in learning new skills quickly.


Ultralearning advises those who want to learn a skill to draw a map of what they need to learn to achieve their goals; in the Craftsmanship Academy, we’ve drawn the map of the things they’ll need to know for them. We will give them enough information to get to the next place on the map. When they get stuck, we give them the next concept, and so on. This way, they get the information when they get to the context they will use it, and they will remember it better in the future. 

Using “just-in-time” learning helps us teach the basics of software development in the short immersion period of the Academy. Going at this speed requires participants to focus on learning their craft. They have weekly and sometimes daily deadlines to keep up with, and they’ll all have the same task to focus on, so they’ll help each other understand concepts as we go. 

We start teaching best practices from day one, and the problems they have to complete help engrain good habits. Giving them what to focus on and creating building blocks of knowledge helps them go farther. This method allows them to learn new skills quickly and thoroughly.


In part three, we’ll discuss how this focused environment leads to directness in teaching, reducing the need to drill and improving retrieval and retention.

In case you missed it, here's Part One: Why Our Craftsmanship Academy Overcomes Academia's Biggest Problem, and check out Part Four: Feedback in the Context of Directness.