Learnable Programming: Thinking about Programming Languages and Systems in a New Way

September 28, 2012 at 11:37 am 9 comments

Bret Victor has written a stunningly interesting essay on how to make programming more learnable, and how to draw on more of the great ideas of what it means to think with computing.  I love that he ends with: “This essay was an immune response, triggered by hearing too many times that Inventing on Principle was “about live coding”, and seeing too many attempts to “teach programming” by adorning a JavaScript editor with badges and mascots. Please read Mindstorms. Okay?”  The essay is explicitly a response to the Khan Academy’s new CS learning supports, and includes many ideas from his demo/video on making programming systems more visible and reactive for the programmer, but goes beyond that video in elaborating a careful argument for what programming ought to be.

There’s so much in his essay that I strongly agree with.  He’s absolutely right that we teach programming systems that have been designed for purposes other than learnability, and we need to build new ones that have a different emphasis.  He uses HyperTalk as an example of a more readable, better designed programming language for learning, which I think is spot-on.  His video examples are beautiful and brilliant.  I love his list of characteristics that we must require in a good programming language for learners.

I see a border to Bret’s ideas.  There are things that we want to teach about computing where his methods won’t help us.  I recognize that this is just an essay, and maybe Bret’s vision does cover these additional learning objectives, too.  The learning objectives I’m struggling with are not made easier with his visual approach.

Let me give two examples — one as a teacher, and the other as a researcher.

As a teacher: I’m currently teaching a graduate course on prototyping interactive systems.  My students have all had at least one course in computer programming, but it might have been a long time ago.  They’re mostly novices.  I’m teaching them how to create high-fidelity prototypes — quite literally, programming artifacts to think with.  The major project of the course is building a chat system.

  • The first assignment involved implementing the GUI (in Jython with Swing).  The tough part was not the visual part, laying out the GUI.  The tough part was linking the widgets to the behaviors, i.e., the callbacks, the MVC part.  It’s not visible, and it’s hard to imagine making visible the process of dealing with whatever-input-the-user-might-provide and connecting it to some part of your code which gets executed non-linearly.  (“This handler here, then later, that handler over there.”)  My students struggled with understanding and debugging the connections between user events (which occur sometime in the future) with code that they’re writing now.
  • They’re working on the second assignment now: Connecting the GUI to the Server.  You can’t see the network, and you certainly can’t see all the things that can go wrong in a network connection.  But you have to program for it.

As a researcherI’ve written before about the measures that we have that show how badly we do at computing education, and about how important it is to make progress on those measures: like the rainfall problem, and what an IP address is and whether it’s okay to have Wikipedia record yours.  What makes the rainfall problem hard is not just the logic of it, but not knowing what the input might be.  It’s the invisible future.

I disagree with a claim that Bret makes (quoted below), that the programmer doesn’t have to understand the machine.  The programmer does have to understand the notional machine (maybe not the silicon one), and that’s critical to really understanding computing. A program is a specification of future behavior of some notional machine in response to indeterminate input.  We can make it possible to see all the programs execution, only if we limit the scope of what it is to be a program.  To really understand programming, you have to imagine the future.

It’s possible for people to learn things which are invisible.  Quantum mechanics, theology, and the plains of Mordor (pre-Jackson) are all examples of people learning about the invisible.  It’s hard to do.  One way we teach that is with forms of cognitive apprenticeship: modeling, coaching, reflection, and eliciting articulation.

Bret is absolutely right that we need to think about designing programming languages to be learnable, and he points out a great set of characteristics that help us get there.  I don’t think his set gets us all the way to where we need to be, but it would get us much further than we are now.  I’d love to have his systems, then lay teaching approaches like cognitive apprenticeship on top of them.

Thus, the goals of a programming system should be:

to support and encourage powerful ways of thinking

to enable programmers to see and understand the execution of their programs

A live-coding Processing environment addresses neither of these goals. JavaScript and Processing are poorly-designed languages that support weak ways of thinking, and ignore decades of learning about learning. And live coding, as a standalone feature, is worthless.

Alan Perlis wrote, “To understand a program, you must become both the machine and the program.” This view is a mistake, and it is this widespread and virulent mistake that keeps programming a difficult and obscure art. A person is not a machine, and should not be forced to think like one.

via Learnable Programming.

Entry filed under: Uncategorized. Tags: , , , , .

Planet CAS: Blogs About Computing At School in the UK Role for research universities in promoting STEM education

9 Comments Add your own

  • 1. David Furcy  |  September 28, 2012 at 12:59 pm


    I strongly agree with (and enjoyed reading) both the original essay and your post. I particularly liked your definition of a program as “a specification of future behavior of some notional machine in response to indeterminate input.” However, let us assume that we are focusing only on true beginners (with no prior programming experience whatsoever), during the first quarter/semester of learning about programming, and maybe also (it’s a stretch, I know) for people who will not make software development their profession, will not care about optimizing their code or writing large-scale programs, etc.). Then could not one make the claim that we can (or should?) teach them programming and problem solving at a high enough level of abstraction that they do not have to have a deep understanding of the machine their program will run on? I think of the functional-first approach to CS1 as supporting this claim to some extent. One of the advantages of pure functional programming is that there is no state and no machine to speak of. In this case, understanding functions, algebraic laws, etc. should be good enough to get started, which is a reasonable expection for college freshmen.

    But in the end, your definition of a program still works: the “notional machine” in the functional-first approach to teaching CS1 is simply the lambda calculus!

    • 2. Mark Guzdial  |  September 28, 2012 at 1:04 pm

      Hi David — we’re in agreement. I care about the “notional machine,” which should be some level of abstraction above the hardware. The lambda calculus is a good notional machine to teach. In fact, I suspect that only professional software developers need to understand the physical hardware, and not all of them need to know that. How many programmers go no deeper than an API, e.g., using existing data structures and never even touching a reference/pointer?

  • 3. Rob St. Amant  |  September 28, 2012 at 1:11 pm

    Very cool. Victor’s create-by-reacting reminds me of a 1982 system from XEROX PARC called RABBIT, which introduced the idea of (information) retrieval by reformulation. What if a user is trying to construct a query to a database, but they don’t know what’s in it? They might not even know what they want in the end. RABBIT shows an example instance, based on a partial description, which the user can learn from and edit to gradually refine a query: “The example instance… serves several purposes: it functions as a template, it permits access to additional descriptors, it provides semantic resolution of potentially ambiguous terms, and it frequently serves as a counterexample.”

    Michael D. Williams and Frederich N. Tou. 1982. RABBIT: An interface for database access. In Proceedings of the ACM ’82 conference (ACM ’82). ACM, New York, NY, USA, 83-87. DOI=10.1145/800174.809764 http://doi.acm.org/10.1145/800174.809764

  • 4. Round 4: A Slight Diversion | Teaching Software Carpentry  |  September 28, 2012 at 2:46 pm

    […] Please read commentary by Mark Guzdial and Neil […]

  • 5. Garth  |  September 28, 2012 at 3:54 pm

    I wish there was a modern version of Rocky’s Boots. For absolute beginners with logic it was very useful and besides, it was fun.

  • 6. Mark Guzdial  |  October 1, 2012 at 12:01 pm

    A couple more reviews of Bret’s essay. I think that all of us are raising a similar set of issues: What about the non-visual stuff? How much can be made visual? http://gasstationwithoutpumps.wordpress.com/2012/09/30/learnable-programming-is-not-necessarily-visual/ and http://academiccomputing.wordpress.com/2012/09/28/experts-can-program-blindfolded/

  • 7. rdm  |  October 1, 2012 at 12:09 pm

    In my experience, the concept of “cause and effect” is particularly difficult to teach: there are a lot of ways someone can “understand what is happening” that work but do not work right.

    The whole “correlation is not causality” issue, for example, illustrates some of the difficulty here. The depth of treatment of the ACID concept in database design can be another illustration…

    Functional programming evades one aspect of this difficulty: it leaves out the time dependent aspect. You have most of the elements of cause and effect, but you no longer have “cause must happen after effect, effect must happen before cause”. Functions are totally repeatable.

    Anyways, callbacks, throw the student head-first into this philosophical issue.

    The only resolution I know of, to this difficulty, is offering a variety of perspectives on the issue and hoping that some of them are interesting, from the learner’s point of view, enough to “connect”.

    One student might like: They’re just subroutine calls, from my code to your code. Another student might like: They’re messages that tell you about the user’s actions. Another student might not understand what’s going on in a callback until they start seeing examples of the information conveyed in a callback. Another student … anyways, you’ve probably seen far more of this than I have.

    Still… almost invariably, a mix of abstract and concrete presentation of concepts (vocabulary and examples) seems critical for learning.

    (And I’ve mixed feelings, here — I’m casually ignoring important issues and I’m also being too long-winded. Oh well…)

  • 8. Claus Reinke  |  October 12, 2012 at 5:38 pm

    Just a quick note on your two assignments and the problems students have with them:
    – have you considered using Coloured Petri Nets (nets with code and data)?
    you don’t even have to introduce a net simulator, just use them on paper/whiteboard to discuss and visualize ideas like asynchrony and non-sequential behaviours, or to model client-/server-systems
    – have you looked into proxy servers? They can be really simple
    (eg, there is a http one in 20 lines of nodejs), so you could configure them for your class problems, and they can be used to get a handle on that client-server data flow (both for visualization and for simulating network issues in a controlled test environment)

  • […] excellent job of describing the big trends in learning to code this last year, from CodeAcademy to Bret Victor and Khan Academy and MOOCs.  But the part that I liked the best was where she identified the […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Trackback this post  |  Subscribe to the comments via RSS Feed

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 10,184 other subscribers


Recent Posts

Blog Stats

  • 2,054,191 hits
September 2012

CS Teaching Tips

%d bloggers like this: