True story: I was once interviewing a candidate for a software engineering job and asked him to write an algorithm to sort a list of words. “You can’t sort words,” he replied, “you can only sort numbers.”
Fearing that we were delving into some sort of zen riddle about what words are, I clarified: “I just mean, sort the words alphabetically. Like at a library or in the phone book.”
He shook his head. “We only learned algorithms for sorting numbers in school. Not words.”
“Well,” I threw him a bone, “maybe we can come up with a way now to sort words. What if you had a list of words in front of you, not on the computer, just on post-it notes, and you wanted to sort them in alphabetical order. What would you do?”
“I can’t,” he replied. “I haven’t memorized that algorithm.”
Yikes.
Cathy Davidson has been arguing recently that we should teach a 4th ‘R’, algorithms, on par with literacy and math. To my delight, what she talks about is not just teaching existing algorithms to kids (“first we’re gonna memorize bubble sort, then on to merge sort“), but rather teaching them how to think about the world algorithmically.
The distinction is an important one. As Cathy says:
Algorithmic thinking is less about “learning code” than “learning to code.”
Cathy’s thoughts on this, as well as talking to folks like Matthew Levine from Google and Mitch Resnick from the MIT Media Lab has convinced me that understanding how to break apart a problem into its composite parts is an essential web literacy skill, which is why it appeared in my recent skill diagram:
I call it “recipe’izing tasks” for two reasons:
- My marketing skills suck.
- I think that the concept of building a recipe helps to emphasize that this is more about a way of thinking and approaching problems than it is about applying well-researched coding algorithms to tasks.
I tested out teaching this skill last night with the BAVC students where I gave them the job of thinking big and thinking small: how do you deconstruct “make a sandwich?” into its specific parts, and how do you deconstruct “how many chickens does the city of SF eat” into a problem that’s estimateable?
One of the coolest outcomes of doing a few of these activities was that I had them split into pairs (there were 4 groups) and tackle the problem: “How often will you hit the letter ‘q’ in your lifetime?” and all of the groups came up with answers that were the same order of magnitude. That certainly doesn’t prove anything, but it was impressive to see how quickly they latched onto the idea of breaking down a complex problem into estimateable chunks.
They also tackled problems like how to break “After you hit a ball in baseball, what do you do?” into a set of steps. Each group discovered their own set of problems (“hmm how do we know if we should run to the next base or not?“) and edge cases (“if we’re tagged out, we have to remember to go back to the dugout“).
We didn’t even discuss code or technical problems, but most programmers would recognize what they were building as a form of pseudocode.
Thinking about the world this way is certainly not specific to web making. But having this type of problem solving in ones mental toolkit is definitely a huge empowering asset when it comes time to take a vague problem and turn it into a set of interpretable steps.
Most importantly, this skill isn’t about knowing a particular coding language: it’s about understanding how to take something you want to happen and think through all of the processes, decision trees, edge cases and exceptions necessary to make it happen.
If you’re interested to hear more about this, Cathy’s going to be talking with us tomorrow (Feb 1st) about this topic, and how we can turn the vague notion of “teaching algorithms is good” into a part of Mozilla’s 2012 webmaker goals.
Michelle,
For me, the whole point of introducing programming to kids is to teach this discipline of algorithmic thinking. It is a critical thinking skill, and the world would be a better place if more people were able to do it!
Thought experiments like “what is the algorithm for making coffee” may be interesting as a way to introduce the topic, but aren’t really useful because the problem is too under-constrained to really be “algorithimizable”. Without a set of primitive operations–an API–you can’t really create an algorithm.
What you seemed to find, at least in the coffee making example, was that your participants fell into the “I’ll pretend I’m a robot” trap. The result was something that was not good technical writing (not useful to a human, even a caffeine-deprived human). Nor was it good pseudocode (not useful to a computer) because the algorithm defined its own API (i.e. the participants picked the granularity of the algorithmic steps and made up the capabilities of the robot). The algorithmic thinking task here is mixed up with another task of designing abstraction boundaries. Designing a good API or a good abstraction is much, much harder than using one, so adding the abstraction boundary definition task to the algorithm task pretty much guarantees bad algorithms.
If you had described your task as “Write a note to a jet-lagged house guest who has never used your kitchen before and doesn’t know where you store stuff explaining how they can make themselves a cup of tea in the middle of the night”, then there would be a sense of the appropriate level of abstraction, what kind of primitives could be used. On the other hand, the task could have been “Write an algorithm for a computerized coffee vending machine,” but in that case, the instructions would probably have to include a list of primitive commands like “wait for a button press” and “eject coffee pod”.
I imagine this sort of exercise could work if one person plays the role of a robot with four commands: “start moving forward”, “start turning clockwise”, “stop moving”, and “stop turning”. Then another person has the task of guiding the human robot around a table or something.
I fear I’m belaboring this. What I want to say is that I think algorithmic thinking is a critical skill, and that the most straightforward way to teach it is to teach simple programming. In programming, APIs are already very tightly defined, and the computer acts as a stern but impartial judge of the correctness of the resulting algorithms!
Chalk me up as another person who doesn’t like pseudocode as a teaching method. I think games like those made by Zachtronics Industries do a much better job at providing a framework for learning to think algorithmically*, since they clearly restrict what you can and can’t say.
* I’d call it “thinking imperatively” though, since these exercise almost always involve imperative paradigms, and almost never functional paradigms.
This is EXACTLY the kind of discussion I want us all to have . . . about everything! I love the blog and I love this response. I love the idea of deconstructing a chicken sandwich and calculating the number of chickens . . . all that . . .and that one needs to structure one’s procedures and algorithms differently for telling a jetlagged houseguest how to make coffee in one’s house and for computerizing a coffee vending machine. . . we rarely, rarely teach at either the tiny level or the macro level. We aim at the middle, the vague, the abstract, the irrelevant, the model, the example, and the imaginatively impoverished. When you start thinking and DOING algorithmically, it’s a different world. The saddest comment I received on my original 4th R blog was that, yes, we teach 3rd graders algorithms . . . how to MEMORIZE them. Really? Really? No wonder we kill kids’ curiosity about science and math. John Seely Brown said it best. You don’t learn science. You learn how to be a scientist, to think and do and test and experiment, as far as your imagination and creativity allow. Talk tomorrow! And dream tonight. ‘night, night everyone!
I agree entirely with the issue you’ve identified. I’ve typically described it and seen it described as the ability to abstract a problem.
It seems like the most important thing to identify during an interview process: never hire someone without the ability to abstract, and prioritize it above almost anything else, because it represents the ability to solve almost any other problem.
The best hackers understand this ability inherently, almost to a fault. I agree with you that we should strive to teach this skill as early as possible, making it a foundation for everything else.
Fundamentally, anyone who doesn’t have the ability to abstract has learned almost nothing, and once they have that ability they’ll need to re-learn or re-evaluate everything else they think they know or understand.
Nice post, Michelle. As I read this, I think back to how I struggled to learn how to code in school. I took class after class and just couldn’t get my head around how to set up the words and numbers on a page to make them do operations. Then, I had this one friend – note> not teacher, who broke it down for me metaphorically (I believe that the problem involved something about going dancing and having the right outfit and such)- and finally a bell went off. Different things work for different people, some learners respond to just seeing code and having at it, and others (like me) need to approach things from a different perspective.
I think that what is key is to have a combination of algorithmic thinking- where you are able to break down or recipe-ize the components of a problem and then, being able to see how those components relate to each other.
My thoughts on what the term “algorithmic thinking” does—and doesn’t—include: http://third-bit.com/blog/archives/4426.html.
Perhaps there’s another inquiry lurking here. While I can imagine ‘thinking algorithmically’, that’s not necessarily the way we behave. How does the development of the cognitive skill influence our behavior – or vice versa? And what does it mean to be a skilled ‘algorithmist’ roaming around in a world of less adroit or less interested folks?