Don’t teach like you code

As programmers, how do we go about teaching people well?

After all, coding has many of the same traits as teaching. Underneath the fancy patterns and elegant frameworks, code is just a set of concrete instructions to do something. Even if one, seemingly obvious, detail is left out, you’ll know soon enough. Code has an order too. You can’t implement a concept before it’s been defined yet, just like you couldn’t teach someone how to multiply before they understand how to add.

But, good coding isn’t like teaching at all. It promotes habits that are entirely counterproductive to the art of teaching. A really good programmer just might make for an awful teacher.

First, rarely do we code linearly. You don’t start from the top and just work your way down to the end of the story. Along the way, a clear concept in your head turns into a half-truth. Part way through writing a method, you might decide you need to track things in an array. After a few minutes, you’ll decide a hashtable works better. If coding against a platform is at all like talking to a student, you’d sound rather unsure of yourself.

Second, coding lets you cheat on the details. We compile our code not because we think we’re done, but because we want to find out what we may have missed. You can usually bucket most compiler errors in the “I was just being lazy” category. A missed instantiation here, a data-type mismatch or non-returned value there. I’m a habitual compiler. A compiler is a lazy programmer’s best friend. Ditto for unit tests, code-hinting and auto-completion.

All these niceties are great for programming. They give us softly padded walls to bounce our code off of. They let us focus on the hard stuff first and not worry too much about perfection in our code-speak. A good programming platform is simultaneously wiping our chin, correcting our grammar, and telling us what we really mean while we spew out semi-coherent lines of instruction. And, the faster and more efficient we are at coding, the more we rely on the platform to steer us in the right direction.

Teaching a newbie is entirely different. Every missed detail is a lost detail. You can’t start your sentences expecting your student to finish them — at least not early on. And unlike a compiler, who invariably will forget your missteps once you correct them, people don’t have as much luck separating the wrong details from the right. You may compile your code a dozen times before you finally get it right, but imagine correcting yourself twelve times before your teaching lesson finally makes sense.

You, my friend, make a terrible teacher.

How do you teach people well? It starts by knowing that what may make you a great programmer will not make you a great teacher.

6 responses to “Don’t teach like you code

  1. The target of teaching is a person, who is intelligent in the ability to derive new knowledge of his own. Teaching is just supplying the right information.

    The target of programing is a machine, and coding is much of the coder's process of processing information.

    No one will teach like he codes. They are just two different things.

  2. @hzhou321

    "Teaching is just supplying the right information." That's way too simple. You have to teach things in the correct order, you have to know when to introduce more advanced concepts at the right time. For example, you wouldn't teach a child to walk in the middle of a busy street first. Teach him to walk where he only needs to concentrate on walking. Only later, you add on concepts like "look both ways" or "be weary of where you walk."

    I've watched experts who are not teachers, teach lots of things…programming, math, poker. These are things I know pretty well. Experts who are not teachers don't teach well because they have a hard time with being explicit about the basics, with ordering concepts correctly, with divulging every single important piece of information that might be obvious only to an expert. It's best described in the book Made To Stick, this concept of "the curse of knowledge."

    Now, all the common missteps I mentioned in the last paragraph are very common and forgiven in programming. You can forget the little things or have things out of order, and relatively immediately you'll know. The compiler yells at you or you get a runtime error.

    And that is my point. Surely no one consciously teaches like he codes. But, being more conscious of how they are different can make you a better human teacher.

  3. I'm not so sure I agree with many of your comments. Let's start however with what we can agree with: Many who teach programming are not good teachers. (Of course, the same can be said for many who teach Algebra, or Spanish, or Chemistry, or …) Just because you're good at programming doesn't mean you're good at teaching, and (unfortunately) just because you're good at teaching doesn't mean you're good at programming. (Too many fall into the latter category as well.)

    Before teaching I was a software engineer in industry for 17 years, and I might even say a pretty good one at that. I took the time to understand the requirements of the task before beginning. (There's a sign in my classroom: "Weeks of coding can save you hours of planning.") If, as you suggest, "Part way through writing a method, you might decide you need to track things in an array. After a few minutes, you'll decide a hashtable works better," I would say that you really didn't think the situation out properly. These decisions should have been made (and potentially unmade and replaced) BEFORE you started writing the method.

    And I take exception with your assertion that we compile code to find out what we missed. I tend to be lazy myself, but I would consider it a black mark on my opinion of myself if I got the errors you describe. Again, if you're missing things like instantiations, data type mismatches or non-returned values, you didn't plan things out well before you started coding.

    I have been teaching now for over 10 years. (I made the change from engineering because it stopped being "fun", but that had more to do with the companies I worked for than programming itself.) My approach to teaching is that I want to instill in a new generation of engineers the love I have for this craft. I want young women and men to catch the same fire for bringing a raw concept into existence. And I want them to NOT be the type of engineer you describe, who pounds a keyboard until the program works. Having worked with more of those types than I wanted, trust me when I say that this path leads to frustration more often than not.

  4. I agree with a lot of what @Mr is saying – taking the time to understand the requirements of any task should be one of the basic preliminary planning steps involved before any coding takes place. Deciding on object relationships, data structures used, etc. should all be thought through before hand for any piece of complex software to ensure that all decisions made will allow for the requirements of the task to be achieved.

    The problem is that these large complex pieces of software are so rare in the world of modern web programming that the planning stages are often way overkill and actually often a detriment to solving a problem, mostly due to the cold fact that there is not enough time budgeted to think that thoroughly about the problem prior to coding up a solution. Twenty or thirty years ago, compiler time and terminal time mattered so much more that you had to make sure everything worked before you wrote any statements down in the machine- it just isn't like that today for most web developers. Our tasks are so simple and their due dates coming up so fast that you often start coding before you've figured all of the nuances. Granted, it doesn't mean that you shouldn't plan as much as you can before hand, but I understand the style of coding that Ka Wai is describing as all too common due to the business requirements of today's web app tasks.

  5. "A compiler is a lazy programmer's best friend. Ditto for unit tests"

    If you're saying that unit tests are a lazy programmer's best friend, I have to disagree quite empahtically.
    1) I doubt a lazy programmer would ever bother with unit tests.
    2) A good programmer makes effective use of unit tests to:
    – improve design
    – assist in refactoring (something a 'lazy programmer' would probably never do).
    – provide a measure of confidence in the system.
    – perform efficient regression testing of the system.

Comments are closed.