Somewhere along the line, I started reading Matt Jadud’s weblog because he talks about pedagogical issues with teaching computer science and I’m interested in this subject both from a personal and a professional standpoint. From the personal side, I spent several summers as a teaching assistant for Computer Science classes at the Talent Identification Program at Duke University and actually taught the introductory class one summer there. (TIP is a program that identifies bright teenagers using the SAT and gives them the chance to take advanced classes over the summer. It’s similar to CTY at Johns Hopkins.) Besides having fun teaching, the experience was also a fascinating problem to solve: how do you teach programming to non-programmers? Having picked up programming at an early age, it was a challenge to try and work out how to impart something that, for me, was very natural. It also helped that I assisted some very good teachers. From the professional side of things, I’m interested in how people learn to program because VB is explicitly designed to be an approachable language for beginners. So how close we do or don’t approach that ideal (and you can certainly argue that with me, if you like) is a big question for us.
A recent entry on Matt’s weblog referred back to an entry he wrote last year called “My First Programming Language(TM)”. Since I only subscribed in the past six months or so, I hadn’t seen it before but I’m glad he linked back to it because it had some very interesting thoughts about how programming languages should be structured for beginners. In particular, he talks about applying Joel Spolsky’s idea of leaky abstractions to programming languages by way of two generic languages named A and B:
In Language A, it turns out that you can’t say anything meaningful without reaching for other parts of the language. While we want to start off with simple bits of code, we must include bits and pieces of the full language to make even the simplest of sentences. Language B, however, is a complete core. We can do simple things simply to start, and if we want to say more complex things, we can. As we grow the language, we don’t have references out into parts of the language we don’t know; instead, we only have references back to the parts of the language we have already learned.
The inability to say simple things simply in Language A is a leaky abstraction. The inability to keep the complexity of the whole language under the covers kills us pedagogically (the blue arrow, below). What should we teach first? Where do we start to build a shared conceptual vocabulary that both the instructor and student can use? Where do we go next if we do manage to find a starting point?
What’s great about his discussion of these two languages is that it captures some of how we think about Visual Basic in a way that I don’t think we (or, at least, I) have been able to verbalize before. When designing new language features, we spend a lot of our time thinking about leaky abstractions and how to avoid them – without calling it exactly that. A good example of this is our design for partial types, which I’ve discussed here earlier. Partial types solve a particular problem for us: they allow us to abstract away automatically generated or templated code from user code. When designing the feature, we had to decide between two designs: one design required the abstraction to leak through into the user code (i.e. explicitly stating “Partial” on all parts of a partial type) and one design kept the abstraction separate at the cost of some explicitness (i.e. not having to specify “Partial” on all parts of a partial type). Each design had it’s advantages and disadvantages, but ultimately we came down on the side of the latter design because we felt it was more important to contain the abstraction, even at the sacrifice of some explicitness.
This does raise a deeper point which Matt references but doesn’t explicitly address. His entire discussion is organized around a split between a “Language A,” which is supposed to be leaky but suitable for “enterprise software,” and a “Language B,” which is supposed to not be leaky but suitable mainly for pedagogy (and not, by implication, enterprise software). The question is: why does there have to be this dichotomy? Why can’t there be a Language C that is designed to be both watertight in terms of leaky abstractions and suitable for writing “real” software? Indeed, our thesis is that Visual Basic does satisfy most of the traits of Language C, but we still end up spending a lot of time having the Language A/Language B argument anyway. Sometimes it’s like the old saying: “There are two kinds of people in the world, those who believe there are two kinds of people in the world and those who don’t.”