Learning the Abstractions
Since much of programming is about creating and manipulating abstractions, it figures that a large amount of education is going to be about leaning those abstractions. Things like classic data structures, the useful sloppiness of O-notation for algorithm analysis, and Design Patterns. But how should we introduce these things to our students?
Should you teach the abstraction first, because that’s what you wind up working with as a programmer? This risks disengagement and confusion. Without a clear concept of what is being abstracted, it’s hard to understand and pay attention. It’s difficult to see the benefit.
Should you teach the old methodology first? This risks building bad habits into the students. They typically feel resentful when you force them through muck and then reveal the pristine diamond-studded gold-brick road they could have used instead.
It’s important to know not only what is being abstracted, but also how and why.
Joel Spolsky, in his post, The Law of Leaky Abstractions notes (emphasis added):
The law of leaky abstractions means that whenever somebody comes up with a wizzy new … tool that is supposed to make us all ever-so-efficient, you hear a lot of people saying “learn how to do it manually first, then use the wizzy tool to save time.” […] tools which pretend to abstract out something, like all abstractions, leak, and the only way to deal with the leaks competently is to learn about how the abstractions work and what they are abstracting. So the abstractions save us time working, but they don’t save us time learning.
And all this means that paradoxically, even as we have higher and higher level programming tools with better and better abstractions, becoming a proficient programmer is getting harder and harder.
Clearly, this indicates that the old methodology should be worked through first. And then students should, in a discussion section of some kind, discuss that methodology as a ‘code smell’ working out (with some guidance) a better solution for themselves. By following this path you motivate the understand through a previously worked example (which can be referred to during the discussion) and can clearly identify the leaks as you work toward the abstraction. Any bad coding habits picked up during the initial slog can be eradicated by revisiting the assignment and applying the new abstraction. There shouldn’t be resentment, because it’s framed as a way of applying some cool new pattern just learned.
I wonder… I haven’t seen anybody teach virtual dispatch and dynamic polymorphism from first principles in this manner. Usually that abstraction is granted as a built-in of the language being learned. Would it be useful to hand-hold the students through designing a virtual method table? could you find a motivating enough example? First doing it some crufty way, then identifying the VMT as a pattern, and finish by refactoring the initial assignment.