I've been teaching programming using my new UI for just about six weeks now, and it's been miraculous and endlessly fascinating to watch a young mind up close. I'm still processing many of my observations and lessons, but I want to describe how one of my students learned something I never meant to teach: consistent indentation.
The only thing I did to help him learn indentation was this: I never ever brought it up. Mostly because I just don't consider it very important, especially at such an early stage. When I wrote programs to demonstrate features I indented as I normally would, then I'd hand over the keyboard, and ignore the fact that my student was abutting each line of code with the left margin.
As the exercises he worked on became longer than a screen or two, though, he started noticing for himself that there was a problem: he was having a hard time explaining his solutions to me, or getting help when he got stuck. I'd often ask, "where is the matching counterpart to this bracket?" Or, "where does this loop begin?" Often he wouldn't know either, and more than once figuring out the answer would also help figure out why his program wasn't working. One fine day last week I showed up to a lesson and found him imitating my indentation.
I continued to ignore this and focus on the specific problem we were working on, but I've been finding myself increasingly reflecting on this one seemingly trivial evolution. Did the fact that he picked up indentation automatically suggest that it was in fact more important than I think? On reflection, I think the lesson is something else: my student magically managed to learn how to indent code, without learning a bunch of undesirable habits and heuristics:
- That indentation is more than an incidental detail.
- That good programming is about following a set of rules.
- That aesthetics matter in code beyond the behavior being implemented.
Basically, my student now indents just like any other programmer (to the extent that anybody should care about it) but knows why he does so, the concrete benefit he derives from it. He is open to changing his habits in the face of changing circumstances. Most important, he doesn't dwell overly on minor local details compared to the prize: understanding what this program does.
Once I happened upon this happy result — learning useful skills without harmful metaheuristics — I noticed that the same arc has been playing out in parallel along several other frontlines. My student used to use single-letter variable names, and now he's starting to use words in some situations. He's starting to add comments. He went from having no comments, to commenting every line (including, yes, “increment x”), to noticing that that wasn't useful. Ok, he might take a few decades to figure out that one. I'm looking forward to seeing the same dynamic evolve in where he draws his function boundaries.
To teach taste, stop teaching rules that must be blindly followed. Your rules are at best a threadbare and bastardized distillation of your life experiences, and at worst polluted with old wive's tales and cargo culting. They're often of no help to others in the situations they encounter in their lives, situations that you've likely never experienced before. Just work with others, focus on your shared goal, use all your skills normally and make them available to emulate. Wait for others to notice problems and realize the wisdom of your ways. They'll be more receptive that way, and they'll practice making up their own minds. And, who knows, you may notice that this rule you hew to so closely doesn't actually matter.
comments
Comments gratefully appreciated. Please send them to me by any method of your choice and I'll include them here.
Anyway, this "teach by example, not by instruction" principle which seems to work so well in IT is why I believe that programming should be taught in vocational schools, same way as carpentry or plumbing, rather than in universities.
I would be really interested to see if they start demanding that programs be indented correctly and start creating rules. Maybe even going so far as to impose those rules on you as you're teaching them.
I'm starting to think there's a step above Naur's "Programming as Theory Building" that applies to building programs in general. That same tendency for new engineers on projects to claim it is badly done and needs rewriting is partly due to them just not having the theory of the program, but that they also have a higher level "theory of building all programs". For example, if your "theory of building all programs" includes a rule of "you solve the problem of easily matching brackets by indenting a certain amount" when you see someone not solve that problem or even solve it in a different way it elicits the same "this program is written badly and needs rewritten" feeling.
_"I would be really interested to see if they start demanding that programs be indented correctly and start creating rules. Maybe even going so far as to impose those rules on you as you're teaching them."_
I think kids wouldn't do this, but someone older and steeped in the way our world works might well be very rule-bound in their thinking. I've written elsewhere about making the world at large less rule-bound. In short, I think the growing brittleness of rule systems (like organization structures or laws) over time is one of the great problems of the world today. To solve it, we need rule systems to be accompanied by scenarios considered in coming up with them, along with the democratized ability for _anyone_ to change the laws as long as all their tests pass. (Adding tests/scenarios might be a more specialized ability. That part is still hazy.)
There's nothing wrong with rules -- as long as we know precisely how long each rule is useful for. I want to live in a world where people aren't conditioned to unthinkingly follow rules.
That's a good point about kids not doing it with you as the instructor, but do you think it's unlikely if they were working with each other?
We're probably talking about two different things (org structure/laws vs theories of programs/programming), so this line might not be interesting to you. But re: your point at the end around rules assumes that it is easy for people to reset and remove rules they're used to. A lot of the rules we encounter in programming become ingrained in the Numbers to Leave Numbers / Form to Leave Form sense which has a lot of benefits in allowing you to rely on intuition rather than having to keep them in working memory all the time. I'm still in the early stages of this idea, but I have a feeling that your speed and success of picking up a new theory of a program/programming depends heavily on your ability to reset your old forgotten rules and pick up new ones (and forget them).
Bateson has written variously about this, and been paraphrased many times, so it should be easy to find more complete accounts, notably in the anthology "Steps to an Ecology of Mind"
Let this whet your appetite: "In all such cases, the step from one logical type to the next higher is a step from information about an event to information about a class of events. Notably, in the case of the dolphin, it was impossible for her to learn from a single experience, whether of success or failure, that the context was one for exhibiting a new behaviour. The lesson about context could only have been learned from comparative information about a sample of contexts differing among themselves, in which her behaviour and the outcome differed from instance to instance. Within such a varied class, a regularity became perceptible, and the apparent contradiction could be transcended." (Bateson 1979:137)
1. My friend Mike Plotz has been writing a series on Bateson.
2. One of the best books I've read on learning is "The Symbolic Species". In particular it has a great description of an experiment in teaching chimpanzees symbolic manipulation, showing that chimps can learn negative reasoning and so evolve symbols. You first spend weeks teaching them to connect up configurations with reward, then you abruptly stop rewarding them for it, and they gradually grok that the presence of the configuration is undesirable. Another great example it describes is a peace treaty ritual between pre-linguistic tribes: if each tribe can be mock charged repeatedly by the other without reacting, you get peace.