TITLE: Small Surprises While Grading AUTHOR: Eugene Wallingford DATE: December 28, 2008 9:34 PM DESC: ----- BODY: Early last week, I spent the last couple of days before Christmas wrapping up the grades on my Programming Languages course for fall semester. While grading the final exam, I seemed surprised by something on almost every problem. Here are a few that stand out: cons and list ... are not the same. We spent some time early in the semester looking at how cons allocates a single new cell, and list allocates one cell per argument. Then we used them in a variety of ways throughout the rest of the course. After fifteen weeks programming in Scheme, how can so many people confuse them? Overuse of accumulator variables ... is endemic to undergraduate students learning to program functionally. Two of the exam problems asked for straightforward procedures following the structural recursion pattern. These problems were about as simple examples of structural recursion as you can find: The largest value in a binary tree is the larger of
• the largest value in the left subtree, and
• the largest value in the right subtree.
The zip of two lists is a list with a list of their cars consed into the zip of their cdrs. Many students used an accumulator variable to solve both problems. Some succeeded, with unnecessarily complex code, and some solutions buckled under the weight of the complexity. Habits are hard to break. I have colleagues who tell me that OOP is easy. I look at their code and say, "yes, but...." The code isn't really OO; it just bears the trappings of classes and methods. Sequential, imperative programming habits run deep. An accumulator variable is often a crutch used by a sequential programmer to avoid writing a functional solution. I see that in my own code occasionally -- the accumulator is as often a code smell as a solution. At a time when the world is looking to parallel computing in a multicore world, we need to find a way to change the habits programmers form, either by teaching functional programming better or by teaching functional programming sooner so that students form different habits. Scheme procedure names ... are different than primitive procedure names in most other languages. They are bound to their values just like every other symbol. They can be re-bound, either locally or globally, using the same mechanisms used to bind values to any other names. This means that in this code:
```    (lambda (f g)
(lambda (x)
(+ (f x) (g x))))
```