# Chapter 2. Emptying the Cup

Can’t you see the cup is already full and overflowing?

The young philosopher

A Zen master of great renown was visited by a young philosopher who had traveled from a distant land to meet him. The master agreed to see him because the philosopher came with high recommendations by his teachers. The two sat under a tree to converse and the subject hastily turned to what the master could teach the young philosopher. Recognizing the flame of youth, the master smiled warmly and started to describe his meditation techniques. He was cut short by the philosopher, who said: “Yes, I understand what you are talking about! We did a similar technique at the temple, but instead we used images to focus!”

Once the philosopher was done explaining to the master how he was taught and practiced his meditation, the master spoke again. This time he tried to tell the young man about how one should be attuned to nature and the universe. He didn’t get two sentences in when the philosopher cut him short again and started talking about how he had been taught meditation and so on and so on.

Once again, the master patiently waited for the young philosopher to end his excited explanations. When the philosopher was quiet again, the master spoke of seeing humor in every situation. The young man didn’t lose any time and started to talk about his favorite jokes and how he thought they could relate to situations he had faced.

Once the philosopher was done, the Zen master invited him inside for a tea ceremony. The philosopher accepted gladly, having heard of how the master performed the ceremony like no other. Such a moment was always a privileged one with such a man. Once inside, the master performed flawlessly up to the point where he started to pour the tea in the cup. As the master was pouring, the philosopher noticed that the cup was being filled more than usual. The master kept pouring tea and the cup was soon full to the brim. Not knowing what to say, the young man stared at the master in astonishment. The master kept pouring as if nothing was wrong, and the cup started to overflow, spilling hot tea on the floor mattresses and the master’s hakama. Not believing what he was seeing, the philosopher finally exclaimed: “Stop pouring! Can’t you see the cup is already full and overflowing?”

With those words, the master gently placed the teapot back on the fire and looked at the young philosopher with his ever-present warm smile and said: “If you come to me with a cup that is already full, how can you expect me to give you something to drink?”

This story was adapted from Michel Grandmont’s “Tasting a New Cup of Tea.”[9] We retell it here to illustrate the sort of attitude a successful apprenticeship requires. The more experience you already have, the more effort you will need to put into “emptying your cup,” clearing your mind of bad habits, setting aside the pride you have in your skills, and opening yourself up to the different, often counterintuitive, approaches of your more experienced colleagues.

By relieving the brain of all unnecessary work, a good notation sets it free to concentrate on more advanced problems, and in effect increases the mental power of the race.[...T]he technical terms of any profession or trade are incomprehensible to those who have never been trained to use them. But this is not because they are difficult in themselves. On the contrary they have invariably been introduced to make things easy.

Alfred North Whitehead, An Introduction to Mathematics

### Context

You are just starting out and have only a shallow understanding of one or two programming languages.

### Problem

You feel your job depends on you delivering a solution written in a specific programming language and of the same standard of quality as your teammates. Alternatively, obtaining a job in the first place depends on your proficiency in a specific programming language.

### Solution

Pick a language. Become fluent in it. For the next few years this will be the main language you use to solve problems, as well as the default skill you hone whenever you are practicing. Making this choice is a challenge. It is important that you carefully weigh the options, as this is the foundation upon which your early career will be built.

If you are asked to solve a problem and it dictates a programming language, let the drive toward the solution direct your learning. If you’re pursuing a job that requires a specific language, build a toy application using that language, preferably an open source project so it is easy for your prospective employer to see a sample of your work. Either way, ask the most experienced and available programmer you know for ongoing help. Having someone immediately available can be the difference between a problem taking minutes or days of your time. However, keep in mind that you don’t want to become completely dependent on your more experienced friend to solve all your problems.

One of the fundamental ways to improve the experience of learning your first language is to have an actual problem to solve. This helps to ground your learning in reality and provides you with your first, relatively large, feedback loop. Learning with the small, contrived examples in books and articles is limiting, and you lose the benefit of applying your discoveries to a problem you have in your head, which, after all, is what you’d be doing on the job. The fundamental way to improve this experience is to seek out opportunities to create feedback loops. In particular, creating short feedback loops helps you gauge your progress. Some languages have better tools for feedback than others, but regardless of the language, you can take some steps to set up a learning sandbox to experiment in.

In Ruby, there is the interactive command-line tool irb. In Rails, there is script/console. Similarly, Erlang has erb. Firebug provides many useful ways to explore the JavaScript runtime in the Firefox web browser, including an interactive shell. Many languages provide equivalent tools.

Sometimes these tools won’t suffice and you’ll need a bigger sandbox. Dave likes to keep an empty Java class open in his IDE when he needs to play around with an unfamiliar API or language feature:

public class Main {
public static void main(String[] args) throws Exception {
System.out.println(/*play with stuff here*/);
}
}

Once you’ve learned enough to actually start writing code, test-driven development techniques can keep you focused on taking small steps and ensure you check your assumptions. Thanks to the popularity of test-driven development, you’ll be hard-pressed to find a language that doesn’t have a testing framework. Don’t hesitate to write simple tests to check your understanding of the language, or just to familiarize yourself with the testing framework.

Start by taking almost insanely small steps; as you learn more, your steps can grow correspondingly larger. For instance, the Ruby language has a feature that lets you apply a block of code to every element in a list and collect the results into a new list. You might write the following code to clarify your understanding of this feature:

require "test/unit"

class LearningTest < Test::Unit::TestCase
def test_my_understanding_of_blocks_and_procs
original = [1, 2, 3]
expected = [2, 3, 4]
p = Proc.new { |n| n + 1 }
assert_equal expected, original.map(&p)
end
end

You’re not limited to using learning tests for learning a language; you can also apply this process to learning about how other people’s libraries work. Over time, these vendor tests (as Ade christened them during a lightning talk at the London Test Automation Conference[10]) can be used to check that upgrading to a later version of a library will not break your system. When the system breaks, the tests point to the new library as the source of the problem since the only functionality they exercise is that which you depend on the library to provide. In well-factored systems, they can also be used to verify that a different implementation of a library’s functionality does all the things you need.

Eventually, you will go from just writing learning tests to writing tests that check your actual code rather than your understanding of language constructs and APIs. Over time, you will find that there are many other techniques beyond simple unit testing that use the computer to verify your work as well as communicate with other members of your team.

The following is a discussion of learning to think differently by learning a new language, but the advice of Ralph Johnson (coauthor of Design Patterns) applies to a first language as well.

Ralph’s advice ties directly into the Find Mentors pattern and the impact that mentors can have on your learning. Thus, the availability of feedback from a nearby language expert should be a major factor when selecting your first language. We should also mention that by choosing a language, you’re also opting into a virtual community of practice with established idioms, social gatherings, and mechanisms for communication. You should take advantage of that support network so that you don’t just learn a language, but in fact join your first community of Kindred Spirits. The preferred work, boundaries, prejudices, and beliefs of this community will be all you have at first. When choosing to learn a language, you should attend meetings of a local group of that language’s enthusiasts (or visit one of their Internet forums) and see if you want to belong to that community.

One of the advantages of belonging to a community that shares its code is that you learn to go beyond the obvious grammatical constructs and start to express yourself idiomatically. But that’s just the beginning. Every language also has its own subtleties that are difficult to pick up solely by reading other people’s code.

For example, in XSLT there is the Muenchian method, while Perl has the Schwartzian Transform and C has Duff’s Device. These techniques can all be learned by reading code, but learning to appreciate why they’re important and when to use them requires the pooled experiences of a community. Sometimes this pool exists only as an oral tradition, and you have to talk to a particular person in order to gain the knowledge. Sometimes the knowledge exists only in the archives of a mailing list or perhaps in an online cookbook, where the lack of context makes it hard to appreciate its significance. In these situations, people new to the language have to immerse themselves in the community for years in order to tap into this pool of knowledge. Nowadays, though, these subtleties are often captured in books like Effective Perl Programming (Addison-Wesley), Effective Java (Prentice Hall), and Effective C++ (Addison-Wesley). Reading books such as these as soon as you have mastered the basic syntax can greatly accelerate your learning and help you avoid common mistakes.

All this will help you dig deeper into your first language. For several years, your first language will be the framework against which you learn other languages. The better you know your first language, the easier it will be to learn your next language. Although you will primarily be using this language to solve day-to-day problems and deliver functionality, periodically take some time to stretch it beyond where you would in the normal course of your work. Stretching the language in unconventional directions will help you discover where one language excels and one language struggles.

Eric Merritt’s blog post “The Shape of Your Mind” dives into how programming languages can have a profound impact on your problem-solving skills:

One danger of digging deep into your first language is getting stuck. It likely will remain with you throughout your career as your native tongue. But do not allow your proficiency in it to prevent you from learning and using other languages. A healthy career should introduce you to the diverse language landscape of software development. Each language provides an opportunity to solve problems using different paradigms. As you move beyond your first language, look for opportunities to learn languages that take a radically different approach than the ones you already know. Apprentices comfortable with an object-oriented language should explore a functional programming language. Apprentices comfortable with dynamic typing should explore static typing. Apprentices comfortable with server-side programming should explore user interface design. Along the way, you will certainly develop preferences for languages and problem-solving approaches, but avoid the dogmatic, religious subcultures that try to push you toward a one-size-fits-all approach. This broadening is the first small step toward the wide-ranging mastery required of a master craftsman.

### Action

Find your language’s specification. Read it. For some languages this may be as easy as picking up a published book. For others there may only be a grammar available. For still others the only specification may exist in the language’s implementation. Consider taking up the challenge of writing the specification.

If the language’s standard library is open source, read through it using the techniques described in the Use the Source pattern. You may not be impressed by the quality of the code you see there, but keep in mind that the writers of that code had no community to learn from and had to make things up as they went. Consider sending them a patch to fix any bugs you spot.

Another approach you can take to building up your knowledge of a language is to ask the people you work with how they chose the first language they mastered. Then add the criteria they give you to the set you already used when you chose your first language. These will come in handy when it is time to choose your next language.

Finally, you can find out more about the idioms we mentioned earlier: the Muenchian method, the Schwartzian Transform, and Duff’s Device. They’re all named after programmers who had a practical problem to solve. Try to track down the problems that these idioms were originally meant to solve, and ask yourself how you would solve the same problems in your primary language.

## The White Belt

As a rule, each step should have a feeling of entrance. This is beginner’s mind—the state of becoming.

Shunryu Suzuki, Zen Mind, Beginner’s Mind

### Context

You have developed a deep understanding of your first language and are walking comfortably on a plateau of competence. Your colleagues recognize your abilities and call on you to help them solve problems in your area of expertise. You have pride in your skills.

### Problem

You are struggling to learn new things and it seems somehow harder than it was before to acquire new skills. The pace of your self-education seems to be slowing down despite your best efforts. You fear that your personal development may have stalled.

### Solution

While retaining the confidence you have gained through your learning, set your previous knowledge aside as you approach new situations. As Yoda so wisely says in The Empire Strikes Back, “You must unlearn what you have learned.”

Wearing the white belt is based on the realization that while the black belt knows the way, the white belt has no choice but to learn the way.

Part of the approach Dave took as a family therapist included maintaining a not knowing stance. Families in difficult circumstances were experiencing a unique reality that, despite his training, Dave knew he could not fully appreciate. While he acknowledged his skills at facilitating constructive questions and conversations, Dave was taught to refrain from believing that he had any expert knowledge into the realities that these families experienced. While this may seem counterintuitive, in reality it fosters an attitude of respect and curiosity that opens up unforeseen possibilities and solutions. Rather than pushing solutions down on the family, Dave’s not knowing stance helped him to collaborate with the family to find solutions as a team.

Taking this approach to learning new technologies accelerates the learning process tremendously. Training yourself to suspend the use of your customary programming idioms allows you to discover new possibilities. However, as a programmer finally feeling proud of achieving a significant level of expertise, taking a step toward ignorance and allowing yourself to look foolish can be painful. But consider the words of George Leonard from the final pages of Mastery:

Or take the following example of a 10-year industry veteran keeping an open mind and learning something new:

As Steve learned, we have to be able to put aside our past experiences and preconceptions to allow new knowledge in. This is especially difficult when trying to learn your second programming language, because it is likely the first time that you have to sacrifice productivity in order to improve your skills. Previously you would have approached problems as empty cups, with few preconceptions about “the correct way” to solve them. Now you must try to avoid synthesizing new and old knowledge until the new knowledge has had time to sink in, and approach this new knowledge with the mind of a beginner. This may mean losing some productivity in the short term in order take a leap forward once you master the new approach.

One of the benefits of adopting this mindset when learning a new language, tool, or business domain is that you are open to learning how to express yourself idiomatically, thus smoothing your communication with the existing community. By avoiding the old problem of “writing Fortran in any language” you gain a far deeper understanding of the new knowledge. Thus, when you eventually reconcile new and old knowledge you are better placed to develop productive insights from both fields.

Take the following Java code as an example. It generates random numbers for the United Kingdom’s National Lottery by printing a set of six distinct numbers from 1 to 49 inclusive:

public class Lottery {
private static final int NUMBER_OF_RANDOM_NUMBERS = 6;
private static final int MAX_RANDOM_NUMBER = 49;

public static void main(String[] args) {
SortedSet randomNumbers = new TreeSet();
Random random = new Random();
while (randomNumbers.size() < NUMBER_OF_RANDOM_NUMBERS) {
Integer randomNumber = new Integer(random.nextInt(MAX_RANDOM_NUMBER) + 1);
}
System.out.println(randomNumbers);
}
}

If you were asked to reimplement this in a slightly different language like Io (which is designed to have a very minimal syntax while still being approachable to mainstream programmers), you could reuse a lot of your Java knowledge and write it like this:

list := List clone

while (list size < 6,
n := Random value(1 50) floor
list appendIfAbsent( n )
)

list sort print

But if you were asked to implement it in a radically different language like J, you would find this approach doesn’t work. Only by “wearing the white belt”—accepting that in a language that doesn’t have loops there must be a radically different but nonetheless valid way of solving problems—can you make progress. So in idiomatic J, the answer is:

sort 1 + (6 ? 49)

Later on we will show you patterns to help you practice, devise toy programs, and consciously reflect on the work you’re doing. These patterns will allow you to appreciate the deeper commonalities between the different sets of knowledge that you possess, and create situations where you can hone your skills without the pressure to maintain your normal levels of productivity.

### Action

Find an opportunity to unlearn something. Ideally, this would be something that forces you to put aside your previous experience.

For instance, take a program you have written in one programming paradigm (e.g., imperative, object-oriented, functional, array/vector-oriented, etc.) and implement it in a language that uses a different paradigm. Make sure your new implementation follows the idioms of the new language. If all the languages you know use the same paradigm (e.g., object orientation), then this is also an opportunity to learn a new paradigm.

This pattern goes beyond programming languages, but that happens to be one area where misconceptions can easily arise. So find someone who uses a programming language or a set of technologies that are unfamiliar to you. Ask that person to explain some of the misconceptions that people from your particular background usually have about their community.

Craftsmen take on only eager apprentices who are willing to learn the craft of software development.

...

Apprentices are an essential part of software craftsmanship because they bring an enthusiasm and drive for learning that infect everyone else.

Pete McBreen, Software Craftmanship

### Context

You have an insatiable excitement and curiosity regarding the craft of software development.

### Problem

You find yourself holding back, conscious of how much more enthusiasm you have for the work than your colleagues do.

### Solution

Despite (and because of!) your inexperience, you bring some unique attributes to your team, including an infectious enthusiasm. Do not allow anyone to dampen your excitement for the craft—it is a precious commodity and will accelerate your learning.

As a software developer, you will inevitably work as part of a team. In any group setting, there is a tendency to conform to the norm, particularly for newcomers. Most teams are not hyper-passionate or overly enthusiastic about technology. Predictably, they are focused on delivering the next project or improving on the aspects of the development life cycle that are causing them pain. Therefore, enthusiastic apprentices can often succumb to the urge to fly under the radar. They either repress their enthusiasm altogether, or allow it to manifest only outside of their day jobs.

There are certainly risks involved in unleashing your enthusiasm on an established team. If morale is low or if the team is not welcoming of newcomers, you will likely get some eye-rolling behind your back. You could certainly make a poor impression on people who value competence more than learning ability, particularly when you expose your ignorance. Like any pattern, this one should not be applied blindly. Team dynamics should always be considered. If you find yourself on a team that does not accept your excitement, you will need to find ways to nurture your passion.

However, on a team that is open to the excitement and contributions of an apprentice, you will provide some unique qualities that more experienced developers rely upon, such as unfettered imagination and enthusiasm. This is the time in your career when it makes the most sense to take risks and speak your mind. You have very little to lose. Your ideas and passions will add intelligence and diversity to your team. In James Surowiecki’s The Wisdom of Crowds, he repeatedly points to diversity of thought as a key ingredient of collective intelligence.

An intriguing study on the collective mind of aircraft carrier crews showed that newcomers played an important role in the complex, coordinated group activities required to safely operate an enormous boat with fighter jets constantly coming and going. The researchers found that it is actually healthier for a team to consist of people with varying levels of experience.

Ultimately, unleashing your enthusiasm is one of the relatively few responsibilities of the apprentice. You may not bring deep knowledge or hyper-productivity, but it is your duty to inject some excitement into your team and question everything. You are in the unique (and temporary) position of having a fresh perspective, which should allow you to offer some useful suggestions for improvement.

### Action

Think of the last time you had an idea but didn’t propose it. Find the person you would have suggested it to and describe your idea to her. If she points out flaws, try to persuade her to help you improve it.

## Concrete Skills

Having knowledge is not the same as having the skill and practical ability to apply that knowledge to create software applications. This is where craftsmanship comes in.

Pete McBreen, Software Craftsmanship

### Context

You are seeking a role on a talented team of craftsmen that will provide you with better learning opportunities than you currently have.

### Problem

Unfortunately, that team has no incentive to risk hiring someone who may not be able to directly contribute to the team’s workload. The team also faces the possibility that you may not even be able to indirectly contribute, such as by automating some simple manual tasks.

### Solution

Acquire and maintain concrete skills. Even though one of the things that an apprentice brings to a team is an ability to learn quickly, the possession of discrete and demonstrable ability with specific tools and technologies increases the likelihood that you will be trusted to contribute indirectly until you start to gain stature.

Some of the concrete skills you should acquire will be little more than mechanisms to get you past crude HR filters and managers who construct teams by playing buzzword bingo. Others will reassure your prospective team members that you can be put to good use and will not require “day care” (Organizational Patterns of Agile Software Development, p. 88). Examples of concrete skills include writing build files in various popular languages, knowledge of various popular open source frameworks like Hibernate and Struts, basic web design, JavaScript, and the standard libraries in your language of choice.

The point is that you will often require hiring managers to take a leap of faith in choosing you. Concrete skills (which are ideally discrete enough that you can bring toy implementations to an interview) allow you to meet them halfway. The concrete skills you possess are your answer to the question: “If we hire you today, what can you do on Monday morning that will benefit us?” A deep understanding of Your First Language will help establish your credibility and should prove to be extremely useful to your team.

As you begin to make the transition to the role of journeyman you will become less dependent on these skills, as you start to be hired on the basis of your reputation, your portfolio of previous work, and the deeper qualities you bring to a team. Until then, your virtues must be a little more overt.

### Action

Collect the CVs of people whose skills you respect. You can either ask them for a copy or download the CVs from their websites. For each person, identify five discrete skills noted on the CV, and determine which of these skills would be immediately useful on the kind of team you want to join. Put together a plan and a toy project that will demonstrate that you have acquired these skills. Implement the plan.

Get in the habit of going through your own CV on a regular basis. As you do so, extract the concrete skills into a separate list. Are you comfortable knowing that many hiring managers will only look at the items in this list rather than the sum of your experiences?

Tomorrow I need to look stupider and feel better about it. This staying quiet and trying to guess what’s going on isn’t working so well.

Jake Scruggs in “My Apprenticeship at Object Mentor”[13]

### Context

The people who are paying you to be a software developer are depending on you to know what you’re doing.

### Problem

Your managers and team members need confidence that you can deliver, but you are unfamiliar with some of the required technologies. This doesn’t just happen to consultants. It happens to everyone. Perhaps you’ve been brought in because you have a deep understanding of the business domain or some other aspect of the technology stack being used in a team. Or perhaps you’re simply the only person available to do the job.

### Solution

Show the people who are depending on you that the learning process is part of delivering software. Let them see you grow.

According to research by the social psychologist Carol Dweck, the need to appear competent is ingrained into people of most industrialized societies. These societies are increasingly dependent on your competence as a developer, as software creeps ever-deeper into our everyday lives. Yet because of your inexperience, you have many zones of ignorance. You are in a bind. The people around you—your manager, your client, your colleagues, not to mention yourself—are all under tremendous pressure to deliver software. You can see the need for confidence in people’s eyes when they ask you how long feature X will take you to finish. There can be tremendous pressure to pacify them, to reassure them that you know precisely what they want, how you’re going to give it to them, and when.

Software craftsmen build their reputations through strong relationships with their clients and colleagues. Conceding to unspoken pressures and telling people what they want to hear is not a good way to build strong relationships. Tell people the truth. Let them know that you’re starting to understand what they want and you’re in the process of learning how to give it to them. If you reassure them, reassure them with your ability to learn, not by pretending to know something you don’t. In this way, your reputation will be built upon your learning ability rather than what you already know.

Get used to this learning process. This is craftsmanship. There are those who are uncomfortable with this process. Rather than becoming craftsmen, these people become experts, people who achieve expertise on one platform or in one domain and stick with it. Because of their narrow focus, experts can deliver functionality into a specific context better than anyone else. It is certainly important and inevitable for our industry to have experts, but that is not the goal of the apprentice.

Expertise is a by-product of the long road we’re all on, but it is not the destination. Over the course of their journey, craftsmen will work with countless technologies and domains. If, through necessity or interest, they Dig Deeper and develop expertise in one or more of these technologies, so much the better. This is to be expected, just as the runner training for a marathon develops stronger leg muscles. She’s not training to have strong legs; she’s training to run. Like the motivated developer who after working on a Python project for two years achieves a deep knowledge of Python, the marathon runner’s strong leg muscles are a means, not an end.

Some experts will do everything they can to remain wedded to a single context, narrowing the scope of their learning, their practice, and their projects. Craftsmen, on the other hand, need to have the courage and humility to set aside their expertise and wear The White Belt as they pick up an unfamiliar technology or learn a new domain.

One of the most important traits that a craftsman can possess is the ability to learn, identifying an area of ignorance and working to reduce it. Like bare patches in a garden, ignorance can be reduced by cultivating your seeds of knowledge. Water your seeds through experimentation, practice, and reading. You can choose to hide these bare patches from the light, embarrassed by their size, covering them to keep your pride intact. Or you can choose to expose them, being honest with yourself and the people who are depending on you, and asking for help.

### Action

Write down a list of five things you really don’t understand about your work. Put that list where others can see it. Then get in the habit of refreshing this list as your work changes.

If we value independence, if we are disturbed by the growing conformity of knowledge, of values, of attitudes, which our present system induces, then we may wish to set up conditions of learning which make for uniqueness, for self-direction, and for self-initiated learning.

Carl Rogers, On Becoming a Person

### Context

You have identified gaps in your skillset, gaps that are relevant to your daily work.

### Problem

There are tools and techniques that you need to master, but you do not know how to begin. Some of these are things that everyone around you already seems to know, and there is an expectation that you already have this knowledge.

### Solution

Pick one skill, tool, or technique and actively fill the gaps in your knowledge about it.

Do this in whichever ways are most effective for you. For some people, the best approach involves trying to get an overview by reading all the introductory articles and FAQs they can get hold of. Other people find that jumping straight to the construction of Breakable Toys is the most effective way to understand something. Whichever approach works for you, don’t forget to ask around to your Kindred Spirits and mentors to see if anyone already has this skill and is willing to share what they’ve learned. Sometimes others will be trying to acquire this skill as well, and by working together you can make better progress. At some point you will have gained a satisfactory level of ability in this new area, and then you can decide whether it is more productive to dig deeper or to turn your attention to the other gaps in your skillset. There aren’t enough hours in the day to hone all your skills to a high level, so you must learn to make the necessary trade-offs between them.

This pattern is closely tied to Expose Your Ignorance, but implementing it is less of a challenge to your pride because it can be done in private, without anyone else ever finding out the things you did not know. However, as an apprentice with aspirations to mastery, you need to be willing to Expose Your Ignorance as well. Using this pattern in isolation (that is, confronting your ignorance without exposing it) runs the risk of encouraging a culture where failure and learning are unacceptable because everybody does their learning in secret. Remember that learning in public is one of the ways in which an apprentice begins the transition to journeyman. It’s a small step from learning where people can see you to teaching.

On the other hand, it is also possible to Expose Your Ignorance without confronting it. People who do this merely shrug apologetically when confronted by their ignorance, as if to say “that’s just the way it is.” This leads to a lifetime of being humble, ignorant, and overly dependent on other members of the team. Eventually, it leads to teams where each member defends her own little silo of knowledge and shrugs when a problem crosses into someone else’s territory.

So it’s important to strike a delicate balance between this pattern and Expose Your Ignorance. Confronting your ignorance on its own leads to arrogant infovores who never get anything done, while exposing your ignorance without seeing it as a problem to be solved leads to excessive humility and helplessness.

### Action

Take the list of items from Expose Your Ignorance and strive to learn each one, crossing them off the list as you do so. This new knowledge you have may reveal gaps you hadn’t noticed before; don’t forget to add these things to your list.

## The Deep End

If you’ve never fallen on your face, odds are you haven’t attempted anything worth a damn.

Christopher Hawkins, “So You Want To Be a Software Consultant?”[14]

### Context

Taking small, safe steps has left you unsatisfied. You’re beginning to fear that this isn’t a plateau but a rut. On a plateau, you consolidate your skills through diligent practice in order to attain the next level; in a rut, bland competence eventually decays into mediocrity.

### Problem

You need to grow your skills, your confidence, and your portfolio of successful work. You feel the need to challenge yourself with bigger things. This may involve bigger projects, larger teams, more complex tasks, new and business domains, or new places.

### Solution

Jump in at the deep end. Waiting until you’re ready can become a recipe for never doing a thing. So when you’re offered a high-profile role or a difficult problem, grasp it with both hands. Growth only happens by taking on the scary jobs and doing things that stretch you.

This has risks. If you get it wrong and end up over your head you could drown. Thankfully there are many places in IT where you can take risks without destroying your career if you fail. Risks are opportunities seen through the half-shut eyes of fear. This doesn’t mean lying on your resume to get a job you can’t do, nor does it mean tackling challenges without adequate preparation. Instead, it means taking that promotion or foreign assignment when it’s offered, even if the very real possibility of failure is staring you in the face. Being prepared to fail and recovering from that failure opens doors that the timid will never see.

Even though we advocate seeking out the most challenging tasks you are capable of, you still need to remember that if the water level is above your head it means you’re drowning. Even in Enrique’s example, where he was changing his life in a big way, he was still moving to a country where he knew at least one person and could speak the national language. It’s your responsibility to offset the risks of this approach by Finding Mentors and Kindred Spirits who can provide help when you need it.

It’s also your responsibility to Create Feedback Loops, so that if the challenging project starts to spin out of control you can catch it and get help immediately. Applying this pattern should feel brave rather than reckless.

### Action

What is the biggest successful project you have ever worked on in terms of lines of code and number of developers? What is the biggest codebase you have ever built on your own? Write down the answers to these questions, and then see if you can find other dimensions of project complexity and other ways of measuring your projects. Use these metrics to measure every project you have ever been involved in. Now, when the next project comes along, you can draw a chart of all your projects and plot where the new project falls among the others. After a while, you will be able to use this chart to see where your career is heading, and even start to make choices based on it.

## Retreat into Competence

You look at where you’re going and where you are and it never makes sense, but then you look back at where you’ve been and a pattern seems to emerge. And if you project forward from that pattern, then sometimes you can come up with something.

### Context

You are beginning to realize how little you know, or perhaps you have taken on a new challenge and things aren’t working out so well. Or both.

### Problem

As you are introduced to the vast reaches of your ignorance you are overwhelmed.

### Solution

Pull back, then launch forward like a stone from a catapult. Retreat briefly into your competence to regain your composure. Take some time to build something that you know how to build. Then use that experience to recognize how far you’ve come and how much you are currently capable of.

An apprenticeship is a roller-coaster ride. You will experience the thrill of learning new technologies, leveraging your knowledge and creativity to deliver value to your customers. But you will also experience the heart-in-your-throat terror of perceiving just how little you know compared to the craftsmen and experts you meet along the way. It can be overwhelming, particularly when a deadline is looming or when you’re dealing with production issues. Take heart. This is a normal and inevitable phenomenon along The Long Road. Overcoming the fear of your own incompetence is the bridge between Expose Your Ignorance and Confront Your Ignorance.

This pattern is most relevant for people who have stretched themselves far beyond their ability. If your apprenticeship has you taking reasonable-sized steps forward, taking on gradually increasing responsibilities and technical complexity, then you may not need to take shelter in this pattern. But if you are really struggling or are barely keeping your head above water in The Deep End, look for opportunities to temporarily retreat. Sometimes you need to take one step back in order to take two steps forward. When you do this, it is important to turn that backward movement into forward momentum as quickly as possible. That forward momentum is revealed in your possession of more knowledge and greater skill than you had yesterday.

Going backward makes this a risky pattern use, however. Without a consciously chosen limit on how long and how far you retreat, you may find yourself merely surrendering to your fear of failure. It can be very comforting to delve ever deeper into the things you know how to do well. The rewards of expertise are tangible and immediate, but the risks may not surface until it’s too late to do anything about them. When your expertise eventually becomes obsolete, you will be forced to once again face the vast reaches of your ignorance, but this time you may be out of the habit of learning new things and starting again will be that much more painful. In this scenario, the solution to the feeling of being overwhelmed becomes worse than the problem.

To prevent this from happening, you must accept that this pattern is only a short-term fix while you gather your strength to bounce back. Set a time limit (or “timebox”) for yourself, such as “I will spend the next 10 minutes refactoring the JavaScript validation for this page before I optimize the SQL queries that provide the data.” Or “I will spend the next four hours implementing the command-line interface for this tool before I learn how to call this third-party SOAP API.” Or “I will spend the rest of today improving our test coverage before taking on the job of optimizing our code that is affected by Python’s Global Interpreter Lock.”

Another important aspect of this solution is to use the temporary break to seek support from the mentors and Kindred Spirits you have gathered around you. With their support and the boost of a recent display of competence, you should be better equipped to handle the inevitable bumps on the road when you try again.

### Action

Pick something self-contained that you know really well and reimplement it. For instance, Ade likes to implement caching algorithms because they can range from the trivial to the highly complex. They also allow opportunities to reinforce his intuition about design and algorithmic complexity.