How does a good developer become a great developer?

Forget greatness for a moment: How does a decent developer become a good developer?

There is no definitive path from Step 1 to Step n. Heck, it’s not even clear what Step n is. And as logically-minded developer types, the lack of a well-defined route can make for a daunting journey from novice to master.

I’ve spent a fair bit of time over the last few years bumping up against this conundrum. What’s next? How do I go from being a good developer to a being really good developer?

What does success look like?

I do my best work when I have a goal with clear, measurable criteria for success. For example, I want to run a 5-minute mile. Okay. That’s easy to measure, and success is well-defined. I can figure out how fast I can run a mile now, and the Web is full of advice and training programs for getting faster. I can choose a training program, work hard, and I can be confident that I’ll eventually get where I want to be. And it’s so wonderfully measurable that, every week, I’ll know just how close I am to my ultimate goal.

But how do you measure whether you’ve attained the rank of “really good developer?” In short, you can’t. That goal, as stated, is too subjective, too vague, and is simply not measurable. So how do we find something that is measurable?

Much like the goal of wanting to run a 5-minute mile, we can start by looking at where we are as a programmer versus where we want to be. What experiences has a 5-minute-mile runner exposed himself to that a 10-minute-mile runner is lacking? What experiences has the master programmer benefited from that the novice programmer is missing? It’s the experiences that matter.

We’ve all had specific experiences that clearly advanced our skills as developers. We’ve learned a new language that exposed us to a new way of thinking. Or we crafted the perfect design, only to watch it unveil its gross imperfections in the harsh realities of a production environment. And we became better programmers because of it. Some experiences equip you with new techniques. Others expose you to anti-patterns…and allow you to understand why they are anti-patterns. It’s these experiences that teach you, that influence your thought process, that influence your approach to problems, that improve your designs. And conveniently, it’s simple to measure whether you’ve gained a particular experience. (It might be fun to think of them as achievements.)

So it took a while, but I’m becoming more comfortable with the immeasurability of my pending goal: earning the rank of “really good developer.” If such a developer earns this distinction because of his experiences, then maybe we can still have a well-defined path marching in the general direction of “really good developer” and beyond. I suspect that path looks something like this:

Identify the experiences that advance a person as a developer. Select a particular experience to pursue. Pursue that experience to completion. (Achievement unlocked!) Reflect on that experience. Really soak it in. [A] Return to Step 2, this time selecting a new experience.

And what better way to get started with Step 1 than to crowdsource it? Here’s a first cut at a list of programming achievements, loosely organized into groups. I’ll offer multiple ways for you to chime in with your thoughts at the end.

Achievements

Learn a variety of programming paradigms:

Write a program in assembly language

Write an application in a functional language

Write an application in an object-oriented language

Write an application in a prototype-based language

Write an application in a logic programming language

Write an application using the Actor model

Write an application in Forth [B]

Experience the ins and outs of programming for different platforms:

Write a nontrivial web app

Write a nontrivial desktop app

Write a nontrivial mobile app

Write an embedded app

Write a realtime system

Enhance your understanding of the building blocks that we use as developers:

Write a networking client (e.g., HTTP, FTP)

Write a device driver

Write a B-tree database

Wrap an existing library to provide a better (more pleasant) user experience

Write an application or framework that provides a plugin model

Write a testing framework

Write a programming language

Enlighten yourself with koans, katas, and the wisdom of ages:

Complete five code katas

Complete the programming koans for a language that you want to learn

Attend a code retreat

Read SICP and complete all the exercises

Program in the open:

Contribute to an open source project

Have a patch accepted

Earn commit rights on a significant open source project

Publish an open source project

Perform a Refactotum of an open source project

Learn by teaching others [C]:

Present a lightning talk

Present at a local user group

Present at a conference

Deliver a training course

Publish a tutorial

Publish a constructive code review of an open source project

Write a programming book

About the achievements

Now, let’s go meta for a moment. Note that each of these achievements is measurable. Each one is Boolean: you’ve either completed it or you haven’t. For example, it’s hard to measure whether you’ve learned a functional language, but it’s easy to know whether you’ve written an app in a functional language. The latter is observable. Measurable. Boolean. This measurability applies, quite intentionally, to all of these achievements.

Admittedly, the measurability isn’t perfect. Consider the achievement of presenting at a conference: you could certainly do a half-assed job just to say you’ve earned this achievement. But if you’re reading this post, I assume you want to be excellent. You know that it’s lame to phone it in just to cross an item off the list.

Since we’re talking about improvement …

Since we’re talking about improvement, what would you change about this list? What experiences have made you a better developer?

The list is available as a gist on GitHub. Feel free to fork it and add more achievements. (Make sure they’re measurable.)

Or, fork it and mark off the achievements you’ve already conquered. You might even flag the one that you’re currently working on. (For example, check out these forks from Justin Blake, Pierre Chapuis, and Yann Esposito.) [E]

What achievement will you unlock next?

It sucks when flaky tests slow you down 🐌 I'm building a service called BuildPulse to help you expose unreliable tests and regain trust in your test suite. Learn more at buildpulse.io → Learn how BuildPulse can help you win the fight against flaky tests →

Notes

[A] I can’t emphasize Step 4 enough. To get the most out of each achievement, you owe it to yourself to pause and reflect on the experience before you move on to the next one. Introspect. Ask yourself what you learned. Take the time to write down those thoughts. And even better still, share them with someone else and see how your learnings compare to other people who’ve also earned this achievement.

[B] Forth is essentially its own paradigm.

[C] This quote comes to mind: “Whoever teaches learns in the act of teaching …” — Paulo Freire

[D] Nathan Hwang has developed and open sourced a tool for visualizing and tracking your journey through these achievements.

Updated 8/9/2011 4:32pm UTC - Added links to example forks of the achievement list.

Updated 11/27/2011 8:10pm UTC - Added links to Nathan Hwang’s contributions.

–

Thanks to Michael Parenteau for providing the artwork for this post.

Thanks to Michael Nygard, Glenn Vanderburg, Alan Dipert, and Vojtech Rinik for providing feedback on drafts of this post.