Skip to content

On the fundamentals of programming

Let’s start with a story.

I am a volleyball fanatic. I enjoy the game in a way that borders on obsession. Lately I play three times a week for hours at a time. Now, my position is known as middle hitter. As you might have guessed, I’m the guy who stands in the middle of the court and tries to pound the ball through the other team’s floor.

A few months ago, I was going through an athletic crisis. Despite many hours of play I still wasn’t that good at hitting. In fact, I kinda sucked at it. My other skills were decent, but when it came to spiking the heck out of the ball, something wasn’t right. I just wasn’t getting the power other people were and I didn’t know why. I experimented constantly: different arm swings, changing my hand shape, snapping my wrist. Nothing worked. Sad and ashamed, I enrolled in a clinic hoping to cure my hitting dysfunction.

On the first night, the coach ordered us into a hitting drill. No problem. I’m focused, I’m ready; I’m going to crush this ball. I went up for my approach and, well–tapped–the ball over the net. Not impressive. I tried again but with similar results. Discreetly, the coach pulled me aside:

“Did you know you’re taking an extra little hop before you jump?”

“I am?”

“You are. It’s taking away all your momentum so your jump is all wrong. Get rid of that and try again.”

On my next attempt, the set was perfect: high and tight, and I smacked it the same way you’d high-five your grandmother. But that time, I felt the extra hop I was taking. Suddenly it was so obviously there.

I lined up once more. I took three strong steps, leapt in the air, and pounded down the best shot of my life. WHAM! I was elated. The problem I had with hitting was simple: I was deficient in the fundamentals. Everything I’d been tweaking was the minor stuff. Fundamentals are the rock-solid road bed you build on. I’d been rearranging the mile markers on a strip of sand.

The point here is important: mastery of any complex skill requires mastery of its fundamentals. I think this idea just might tell us why there are so many bad programmers out there. And I also think it tells us it’s our fault.

How does one acquire the fundamentals of programming?

I don’t think the answer lies in obtaining a computer science degree. I once interviewed a recent MIT graduate who’d majored in computer science. She was articulate, had a strong GPA, and couldn’t write the pseudocode to sort an array. Really. This is actually a familiar phenomenon. A CS degree tells you how, theoretically, you might spike a volleyball, but that doesn’t mean graduates have ever actually hit one. Of course computer science isn’t really about programming, it’s not even about computers. Now, there are lots of strong coders with CS backgrounds, but that strength is almost always acquired through their own work–they are self-taught.

Academia isn’t much help, so we’re going to have to become deadly code-ninjas on our own. Fortunately, there is a wizened master who can point us in the right direction: Peter Norvig, whose essay “Teach Yourself Programming in Ten Years” wins my personal Nobel for Programming Literature. It’s probably the best advice out there on the subject, and we’d all do well to follow his recommendations. However, despite the fact that Peter is so smart his brain has its own gravitational pull, I think his essay glosses over an important point.

Let’s look at the main thrust of Norvig’s advice:

Program. The best kind of learning is learning by doing. To put it more technically, “the maximal level of performance for individuals in a given domain is not attained automatically as a function of extended experience, but the level of performance can be increased even by highly experienced individuals as a result of deliberate efforts to improve.” (p. 366) and “the most effective learning requires a well-defined task with an appropriate difficulty level for the particular individual, informative feedback, and opportunities for repetition and corrections of errors.”

This is clearly good advice. Surely that MIT graduate could have written me that algorithm if she’d, you know, written code before. But check out the quotation Norvig cites. Where exactly does one find well-defined programming tasks of an appropriate difficulty level? How about informative feedback and corrections of errors?

Well?

It turns out that there’s a shortage of things like this for programmers. Especially new ones. This is a serious problem, and it is this I blame for the huge numbers of coders who lack the fundamental skills of our craft. Worse, this is our own fault: only people already skilled in an activity can devise effective training for newcomers. Even worser: when you lack skills in the fundamentals you almost never know it. I had no idea why I couldn’t spike a volleyball.

So how do we fix this? We do what all great thinkers do: steal a great idea from somewhere else and reuse it. So here’s my solution, shamelessly grabbed from a different, but related area of my life:

To become a better programmer, one should practice like a musician.

Bear with me…

A beautiful piano sonata is the product of thousands of perfectly executed notes. If even one note is misplayed you have cacophony. However, the consideration of individual notes never enters my mind while playing. Instead, I’m thinking about making the phrases flow together, the winsome arc of the melody, or keeping the steady beat of the bass line. It is these things that create music from mere notes. I’m able to think of these things because my mind is free from worrying about playing individual keys, and my mind is free because of my mastery of the fundamentals. The study of classical piano (and every other musical endeavor) devotes ample time to performing exercises. There are perhaps hundreds of books full of them. Compared to a real piece of music they are simple and repetitive, but each exercise isolates and drills a vital skill. This focused practice makes such skills automatic–I can play a very fast run of notes smoothly and accurately because I’ve quite literally practiced it thousands of times. I no longer need to think about it. Because of this, I am a better pianist.

The application of these ideas to programming should be clear. When I’m focusing on the overall musicality of a piece, I’m operating at a higher level of abstraction. Individual details have faded away, and I’m able to focus on making something beautiful. The same skill is required for creating beautiful programs. If you must spend brain cycles struggling with minute implementation details you have no hope for making your solution elegant.

So let’s take this musical idea and alter it slightly. After all, when it comes to programming exercises, coverage is more important than repetition. Not remembering how your language retrieves values from a hash is far less damaging than not knowing hashes exist in the first place.

Fortunately, I can already point to an excellent example of these sort of problems. I believe newcomers would learn more about programming per unit time by working through Ninety-nine Prolog Problems than almost anything else. (Replace Prolog with your language of choice). With the ability to check your answers and also post questions on a wiki, we’ve even covered the “correction of errors” and “informative feedback” requirements mentioned above. Also excellent is The Python Challenge, a series of riddles with programmatic solutions that get progressively harder over time. The site is massively popular and makes people better programmers. Truly, this is a phenomenal start, but there’s much more to be done.

So how about it guys? What are the first fifty programs someone should write to break out of that painful newcomer phase? What topics would they definitely have to cover? Later, what programs must one write to reach hacking virtuosity? I also like to think about this a different way: what problems would you be embarrassed to tell your coworkers you can’t solve?

I think these questions are important, and they just might help improve the overall quality of programmers out there. If you accept programming as an art, why don’t we treat it like one? Let’s start practicing like musicians, and maybe we can create something beautiful.

35 Comments

  1. Sid wrote:

    well i read stuff like this and get all worked up… but its a motivation thing…. hard to keep it going for long.
    :-(

    I did start python challenge way back…. then forgot all about it. Altho it was pure fun doin those.

    Friday, December 14, 2007 at 11:56 am | Permalink
  2. Stu wrote:

    http://projecteuler.net/ is a website which has good little programming exercises which are good to use if you’re picking up a new language. Or even if you’re learning your first language and thus essentially learning “how to program” – they are still good problems.

    Friday, December 14, 2007 at 12:05 pm | Permalink
  3. Ajay wrote:

    Check out the book ‘Programming Challenges’. It’s basically the ACM programming contest training manual. Problems encompass a wide variety of algorithms. And they are annotated with a relative difficulty level. There’s even an automated site (www.programming-challenges.com) that checks your source for you.

    Friday, December 14, 2007 at 12:09 pm | Permalink
  4. Fwiffo wrote:

    Yes! This is exactly correct. This method is exactly like practicing problems in a game of strategy like Go or Chess (see, for example, http://www.goproblems.com).

    Your comparison to music – stringing phrases together – is also spot on. Experienced Go or Chess players will be able to remember whole games, which may consist of a couple hundred moves in the case of Go. But to an expert, it’s like remembering a song or a poem. “Mary had a little lamb, whose fleece was white as snow, and everywhere that Mary went, that lamb was sure to go.” Just that line has 112 characters, but it’s the simplest thing in the world to memorize to someone fluent in English. The same it is with a song for an experienced musician, or a program for a programmer.

    Programming is about putting together idioms and patterns you’ve acquired over the years, not about stacking up individual lines or instructions.

    Friday, December 14, 2007 at 12:39 pm | Permalink
  5. Ben wrote:

    Fwiffo: great comment! I’m a go player myself and when I outlined this article I was planning on mentioning tsumego. Didn’t make the final cut but you’re spot on.

    Friday, December 14, 2007 at 12:45 pm | Permalink
  6. desNotes wrote:

    I can’t get motivated by doing problems or challenges on any particular language. What I do is either look around and get involved in an Open Source Project or start a small one on my own. There are plenty to choose from on Sourceforge.net and http://code.google.com/.

    But, again, that is just me.

    desNotes

    Friday, December 14, 2007 at 12:58 pm | Permalink
  7. I was a horrible coder. I’d flail at the keyboard, hoping to accidentally get the right things in the right place to make the code work correctly. More often, I’d make it worse not better.

    That didn’t change until I got a boss who was an excellent coder. I spend a lot of time watching him code. Sometimes, whn I was coding, he’d often lean over my shoulder and hit the delete key while I was trying to type (he was the silent type). It was his making me retype the code (again), correctly, that eventually lead to me being able to belt out just about any piece of code.

    From that experience I understood that like a lot of skills, programming can’t be taught to you in a classroom, or from a book. Your actually best if you apprentice with a master coder and learn directly from that real experience. There is lots of great work on the many different ways that different people learn things, but for me at least, I still think that to learn how to code well you need to sit there and watch someone else do it correctly. If you pay attention, you’ll definitely learn something.

    Paul.
    http://theprogrammersparadox.blogspot.com/

    Friday, December 14, 2007 at 1:22 pm | Permalink
  8. Here are some, from a venerable source: http://codekata.pragprog.com/

    Friday, December 14, 2007 at 1:39 pm | Permalink
  9. Tim Morton wrote:

    This reminds me of Dave Thomas’ Code Kata idea. See this: http://codekata.pragprog.com/

    Friday, December 14, 2007 at 2:03 pm | Permalink
  10. matt wrote:

    Another thing for your analogy that might’ve helped:

    To increase your hitting skills, you should hit things other than a high lofter in the middle. Hitting the quick, the back quick, tandems, a hut, or a 10 ball might have also helped to reveal your poor approach as they often require slightly different approaches.

    Similarly in programming if all you ever code is in one problem domain (or one language) you’ll miss out on the knowledge that comes from the glimpse you’d have from these other domains.

    Friday, December 14, 2007 at 2:46 pm | Permalink
  11. dAvid wrote:

    While not the holy grail, I found the Top Coder website was a good place to start.

    The competition side helps the motivation going.
    And I found both hour long competitions, and week long competition challenging in their own ways.

    Since the same kind of problem tends to come back, it’s the same thing as doing piano exercises.

    Friday, December 14, 2007 at 4:23 pm | Permalink
  12. Jonathan wrote:

    Wow. Great article. Please, write some more! :)

    Friday, December 14, 2007 at 4:38 pm | Permalink
  13. karan wrote:

    Bingo , ur so right . Its so easy to gloss over things . I feel reading code + writing code + loving code = cool programmer

    sites like http://www.topcoder.com espcially help the cause.

    Friday, December 14, 2007 at 4:45 pm | Permalink
  14. Michael P wrote:

    Thank you for this. I needed to hear it. I have a computer science professor who does her best to discourage me from pursuing a career as a web developer, because she believes I can’t do the programming and wants me to believe the same. What she doesn’t understand is that I’m still learning–I’ve just begun, actually.

    Give up on another if you must, but never tell someone to give up on themself.

    Thank you for the encouragement.

    –Michael

    Friday, December 14, 2007 at 4:48 pm | Permalink
  15. Thijs Blaauw wrote:

    and couldn’t write the pseudocode to sort an array.

    And why would she need to do that. Sorting is a solved problem. Every programming environment has a generic solution for sorting. I don’t say it is a simple problem, and you need to know the the big O characteristics of insertion sort, selection sort, quicksort and merge sort, to know which one to use in a specific case, but I see no reason why you should be able to reproduce these as pseudocode during an interview.
    Not everyone is as smart as C. A. R. Hoare (no, being able to reproduce quicksort isn’t the same).

    Friday, December 14, 2007 at 4:51 pm | Permalink
  16. Thijs Blaauw wrote:

    In my previous post I commented on a small detail of this article, that is, should a (novice) programmer be able to reproduce a sort algorithm (no).
    I do like the idea that programmer should practice like a musician (to become a master).

    Friday, December 14, 2007 at 5:28 pm | Permalink
  17. ideatagger wrote:

    I am not a programmer but would like to learn Ruby, Python or similar to develop prototypes for some of my ideas. I think it would be a good idea for someone to offer a training course in programming where the student brings an idea that they want to implement and over the duration of the course writes the required code under the guidance of the teacher. For the student, it is kind of like paying for your application to be developed but learning to do it yourself at the same time. Next time round, he may well be able to do it all by himself.

    Friday, December 14, 2007 at 6:02 pm | Permalink
  18. she wrote:

    why everyone is a rush?

    why is not everyone living forever???

    Friday, December 14, 2007 at 6:24 pm | Permalink
  19. Dan D. wrote:

    A basic interpreter (not a BASIC interpreter) for, say, a Pascal-alike, and everything it takes to get to that point is high up on the list.

    Friday, December 14, 2007 at 7:32 pm | Permalink
  20. Michael wrote:

    You make some excellent points, though like others who have commented, I have found what improves my style and abilities more than anything so far has been code review. I think the best approach, for me anyway, would probably be some combination – for instance, on the Python Challenge, coming up with a solution that works and then sending it over to somebody more experience for advice and constructive criticism on how it could be better. This will, of course, only work on fundamentals when just as often it’s important to get other perspectives on larger projects.

    Thanks for the great post! I’m working on improving my fundamentals because of it.

    Friday, December 14, 2007 at 9:29 pm | Permalink
  21. r. clayton wrote:

    You missed the point of your own post:

    Discreetly, the coach pulled me aside: “Did you know you’re taking an extra little hop before you jump?”

    and then

    Academia isn’t much help, so we’re going to have to become deadly code-ninjas on our own.

    which causes you to go on and praise the quote

    The best kind of learning is learning by doing.

    as good advice despite the fact that all your doing volleyball was getting you nowhere until someone told you “you’re doing it, but you’re doing it wrong.”Your point missing carries over to your second metaphor too: how do musicians practice? Under the direction of a master, or at least with peers (I’m overstating the case; to my mind John Coltrane or Glenn Gould are possible counterexamples). Even if they’re woodshedding alone, musicians most likely have someone or something in their head or their ears they’re implicitly comparing themselves against.As some of your other commenters have indicated, your point should have been “how can I find the person (or better: people) who will orient and accelerate my practice?” By ill-founded generalization you’ve dismissed a major source of mentors, but that’s not a severe error because there are other sources. But where? That’s the question.

    Friday, December 14, 2007 at 11:04 pm | Permalink
  22. Adam wrote:

    I can’t think of any way to soften the cliche, so I’ll just say it: Learn Lisp.

    Wait! Either your eyes just glazed over because you’re more sick of hearing that than reading about Ron Paul, or your eyes lit up with the righteous affirmation of the already-converted, in which case I probably lost you by ripping on Ron Paul. But bear with me.

    I’m not evangelizing — though Lisp is a fine language in many ways, one of its virtues that’s often overlooked (because it’s not really a virtue) is that it’s not very widespread and the community is about as supportive as Ted Nugent at anti-war rally.

    Sure, there’s some decent books out there, but you can’t get anywhere in Lisp without learning the fundamentals. When using Rails or PHP to write a web app, it’s often harder to make something *not* work than the other way around. Lisp hackers, on the other hand, would rather write their own browser than spend 15 minutes Googling for a library (since for many of them, it takes less time to write the browser). So generally, if you want something done, you have to do it yourself, and you have to understand how it works.

    The other recommendations above are all good as well, but they seem to me to be more about style and refinement than the basics — the “hops” that you might not otherwise notice. There’s a library out there for damn near everything. Saying that sorting is a “solved” problem is like saying oxidization is a “solved” problem in rocket science. The JPL appreciates your confidence and all, but maybe you should go interview at the fireworks company down the street. As a janitor.

    Friday, December 14, 2007 at 11:28 pm | Permalink
  23. A few angles on this one:

    Firstly, learning style. I’ve taught a LOT of coders, and they seem to fall into two categories – those who need theory first, as a framework, and then practice to flesh it out; and those who need to get their hands dirty to start with, and gradually the bigger picture becomes clear to them. If people can identify their own learning style, the way forward becomes easier.

    Second – breadth first, or depth first? I’ve worked (professionally) in about 15 languages, last count; while I’m relatively agnostic, I found that I learned something new, profound, and possibly interesting with each new language. Oftentimes it was not from any characteristic of the language itself, just the change to my attitude when working with a new syntax, a new “right way” of doing things. (Python and Ruby especially were good for that, but only as a change, IMO).

    Finally, some specifics: Obviously, algorithms. Then application of patterns. OOP. Refactoring (and the smells thereof). Write a decent ORM solution by hand. I found metaclass hacking a great crossover point (and javascript a great language for it – no, seriously. Mind you, I’m a moz-hacker – that may be bias.) Writing an interpreter or compiler from scratch is another one. Maybe as an esoteric side trip, a few kernel modules. Finally, something wickedly performance critical – vertex or pixel shader, maybe, or anything in physics and lighting.

    I would also reiterate what a few others have said more clearly – code review and mentorship is key. (Mind you, working on O/S and knowing every commit is indexed by Google code search *is* kind of like code review).

    Saturday, December 15, 2007 at 1:47 am | Permalink
  24. joe wrote:

    Tip: Give your site more contrast. Small black print on a gray backgroud is brutal on the eyes. (Ed note: agreed, done).

    Saturday, December 15, 2007 at 3:08 am | Permalink
  25. Vasudev Ram wrote:

    Very interesting and thought-provoking post – thanks!

    I agree with many of the points you mention, particularly about practising a lot on the smaller details of programming. And the music analogy is spot on.

    Will think about this post some more and possibly comment later.

    The Python Challenge looks interesting too – thanks again. Going to try it out.

    Vasudev Ram

    Saturday, December 15, 2007 at 9:41 am | Permalink
  26. Colin wrote:

    Great post, hope to see you writing more. I agree with the comment that you slightly missed the point, while programming is fundamentally a self-taught exercise, mentoring is essential. Well, maybe not essential, but how long would it have taken you to notice the hop?

    One of the best exercises in programming I’ve done recently is the TXL challenge (http://www.txl.ca/nlearn.html), which I recommend to all programming language geeks because it’s just plain cool. It’s essentially mentoring through a series of progressively more difficult exercises. I highly recommend it.

    Monday, December 17, 2007 at 4:24 pm | Permalink
  27. ValRe wrote:

    Oh, this is so true! I learned several different languages through higher education, but after I earned my degree, I couldn’t make anything *useful*. I could “Hello, world!” and add A + B, haha. It was several years before I found someone who gave me the jumpstart I needed. Now I just need to find someone for the next level up…

    Friday, December 21, 2007 at 2:00 pm | Permalink
  28. spot wrote:

    The very very very best place to start, the Bible of the fundamentals, is Donald Knuth’s The Art of Computer Programming. Starts with the *useful* part of computer science, which is just describing how the abstract machine “works.” Then goes from top to bottom presenting problems to solve, from the “did you read any of this” sort of simpletons to extremely advanced mathematics, some problems that have not yet even been solved but are essentially in the domain of computing, some that have been solved since he wrote it.

    I enjoyed reading this very much. The same issues of fundamentals go for project management as well. While it can and has been done, it’s just too painful to try to design an algorithm by hashing it out in code (heh) — get the design worked out, then start coding. In this sense, every programmer should be their own project manager.

    As for mentoring, I think it is a unique problem. I’ve been programming for 25 years, from about the time that the commodore was kicking and being kicked around. I taught myself — there was no one else. But unlike volleyball, you can step back from coding, watch your call stack, and see for yourself where your short hops are. And you get better that way. So there are thousands of guys just like me. But we had the advantage that the technology was so infantile compared to today’s gargantuan code stacks. You used whatever computer came your way first, and you started writing conditional loops.

    These days though, the fundamentals really are obscured by all the adornments we’ve made with all those decades worth of conditional loop routines. So maybe we have to reach out and mentor, even though we all started out as socially isolated geekoids…hmmm…I dunno I’m still pretty antisocial. I think I’ll give that kid a link to Knuth’s book and a pat on the head. He’ll be outcoding me in no time….

    Friday, December 21, 2007 at 3:33 pm | Permalink
  29. Vida wrote:

    good material thanks

    Tuesday, March 11, 2008 at 8:59 am | Permalink
  30. allan wrote:

    it’s so beautiful i almost had tears in my eyes..
    haha.. i kid.. i don’t cry..

    but really, it hits the point..

    thanks for the guide.. i will now spend the rest of my teenage days in front of a terminal studying the essence of what you said.. or something almost like that.. i have a life anyway.. xD

    Friday, March 21, 2008 at 5:06 am | Permalink
  31. i need a mentor to gide me through my it studying and i cant find one . please help. i dont mean hackers bt a mentor 10ks

    Wednesday, April 2, 2008 at 3:38 am | Permalink
  32. sehar wrote:

    i cannot understand how to make program in programming fundamentals

    Thursday, June 26, 2008 at 12:52 am | Permalink
  33. ashaju taiwo wrote:

    please can you give me a self guide introduction to programming

    Thursday, October 23, 2008 at 10:00 am | Permalink
  34. ashaju taiwo wrote:

    please can you give me a self guide introduction to programming and what i ought to know before i starts writing a series of program. secondly, what types of program do we have.

    Thursday, October 23, 2008 at 10:12 am | Permalink
  35. Semwenda Samson AC wrote:

    thanx very much for the basic foundation, m a second year college student i was dreaming to be ajournalist but when i wakeup! i found ma self in the computer schoolk when programming is my favourity, bt i dnt knw where to start.
    can i plz get the answers on the following

    - what is the first this to do if i want be a programmer
    - the very basic notes for the begginers like me
    which language is good for the begginers to understand faster and which is good and marketable
    thanx alot

    Friday, June 19, 2009 at 11:04 pm | Permalink

3 Trackbacks/Pingbacks

  1. purrl.net |** the web's most interesting news **| on Friday, December 14, 2007 at 2:05 pm

    The web’s most interesting stories on Fri 14th Dec 2007

    These are the web’s most talked about URLs on Fri 14th Dec 2007. The current winner is ..

  2. roScripts - Webmaster resources and websites on Friday, December 14, 2007 at 4:15 pm

    On the fundamentals of programming : Codeulate.

    On the fundamentals of programming : Codeulate.

  3. [...] It is a late entry to the running for 2007, published on a personal weblog on the 14th of December. The author, Ben Orenstein, is a software developer, and the essay is titled On the fundamentals of programming. [...]

Post a Comment

Your email is never published nor shared.