Sign In

Communications of the ACM

[email protected]

What Help Should We Provide to Students Learning to Program?


View as: Print Mobile App Share: Send by email Share on reddit Share on StumbleUpon Share on Hacker News Share on Tweeter Share on Facebook
Mark Guzdial

Last week, we held an amazing seminar at Dagstuhl on Notional Machines and Programming Language Semantics in Education. You can find my blog post to kick off the week here. There is a huge amount being written about the seminar already (see the Twitter stream here), with a detailed description from Andy Ko here in his blog and several posts from Felienne on her blog. Ben Shapiro has a guest post summarizing the workshop theme coming out in my blog this week.

The big insight for me this week was about the diverse kinds of supports that we can and should provide to students learning to program. Programming is WAY too hard right now. One of the reasons we have trouble getting teachers to try programming is that it frightens them off. We can make it less scary and easier to learn with more supports. We in computer science often believe that we should not provide help to students because it will somehow hinder their learning, that they'll learn it better if they struggle and figure it out for themselves. It’s simply not true. Direct instruction works and is much more efficient than discovery learning (read here and here and here).

A notional machine is a human-facing, student-accessible explanation for how some aspect of the computational machine works — it might be an explanation of a language feature, or an explanation of some aspect of a running program (e.g., how swap() works). To be able to debug a program, a student needs to understand it, i.e., to have a mental model of how the program works. A student has to be able to predict what their program does, simulating it in their head. A notional machine is a teaching tool for helping the student develop a successful (predictive) mental model.

During the seminar week, lots of other things were suggested as kinds of notional machines. I ended up realizing that those other things are useful scaffolding for students, but they weren’t notional machines. Scaffolding is a big umbrella term for lots of kinds of supports that help a student with programming (see a definition of educational scaffolding here). A notional machine is one kind of scaffolding.

Other kinds of supports that were identified this week:

  • Metaphors: "You can think about variables as a kind of box." That doesn’t tell you how the machine does something. It’s an attempt to explain using prior knowledge. "Variable as box" is a particularly frequently used metaphor which turns out to lead to a wide variety of misconceptions by students (see post here), like that the code "a=2; a=3;" means that the variable "a" contains both 2 and 3.
  • Actions, tips, and tricks: "If you’re not sure what’s going on in a function or method, first put in a print or alert call to show you that you made it into the function or method." That doesn’t tell you how things work, nor does it increase your understanding. It’s a really useful action to take when trying to understand.
  • Visualizations and representations: Python Tutor is one of the most used program visualizations in the world. It is not a notional machine — if you have a notional machine at hand, you could use it to interpret the visualizations in Python Tutor. Python Tutor gives you a picture of your program running, but it doesn’t actually provide much help for understanding that picture.
  • Worked Examples: One of the most powerful supports for students is showing them a working piece of code (structure) with an explanation of what it does (behavior) and why it was written (function). That last part is particularly important. We often give examples of code to explain some computational idea (like my "a=2; a=3;" from a few lines up) that don’t actually do anything useful! Our brains are wired to learn useful knowledge. One of the reasons why learning to program is so hard is that we mostly expect students to want to learn to program. We should show code that does useful thing. Over and over again at the seminar, we heard evidence that a grounded, concrete, working piece of example code was one of the best kinds of supports we can provide to students. "Want to learn FOR loops? Go write another program that uses them" is a terrible thing to say to a beginning student. Humans are wired to learn from examples. Just telling students to go struggle with another problem is worse than useless — it’s cruel when we know how to do better.
  • Improved languages and IDEs: The most important lesson that I learned for my personal practice as a teacher is that JavaScript is just too hard to support with a notional machine. Have you ever seen the human-facing (not formal semantics) description of how "==" works in JavaScript? Andy Ko kindly provided it to me — see here. This is just too hard to explain in its entirety. I’d rather students learn it in useful bitesize chunks. We need language levels and new programming tools to help students gradually develop all of this knowledge. It’s too big and complex to explain even with multiple good notional machines.

A big outcome of this seminar at Dagstuhl was a shared understanding (by at least many if not all participants) is that "It’s not all notional machines." Notional machines are a big and powerful idea, but it’s just one tool in our toolbox. Now that we’ve identified more tools, we can work to make all of them better and more useful for our students.


 

No entries found