Joshua Bloch, in this oldie but goodie:
The general lesson that I take away from this bug is humility: It is hard to write even the smallest piece of code correctly, and our whole world runs on big, complex pieces of code.
Having just written a small interpreter for my programming languages course, I, too, am feeling humble. Even in code that couldn't possibly go wrong, I had a small bug that bedeviled me for fifteen minutes. (You have to dereference those bindings in order to get the cells you want to mutate...) The experience is good preparation for a couple of software projects I hope to do this summer and for my compiler course this fall.
Oh, and Bloch's old post reminds me that it may be a good time to work through "Programming Pearls" again. It's been a while.

In today's edition of "Sounds great, but...", I point you to Learn calculus like Huygens, a blog entry that relates some interesting history about the relationship between Gottfried Leibniz and Christiaan Huygens, "the greatest mathematician in the generation before Newton and Leibniz". It's a cool story: a genius of the old generation learns a paradigmshifting new discipline via correspondence with a genius of the new generation who is in the process of mapping the discipline.
The "Sounds great, but..." part comes near the end of the article, when the author extrapolates from Huygens's attitude to what is wrong with math education these days. It seems that Huygens wanted to see connections between the crazy new operations he was learning, including second derivatives, and the real world. Without seeing these connections, he wasn't as motivated to put in the effort to learn them.
The author then asserts:
The point is not that mathematics needs to be applied. It is that it needs to be motivated. We don't study nature because we refuse to admit value in abstract mathematics. We study nature because she has repeatedly proven herself to have excellent mathematical taste, which is more than can be said for the runofthemill mathematicians who have to invent technical pseudoproblems because they can't solve any real ones.
Yikes, that got ugly fast. And it gets uglier, with the author eventually worrying that we alienate presentday Huygenses with a mass of boring problems that are disconnected from reality.
I actually love the heart of that paragraph: We don't study nature because we refuse to admit value in abstract mathematics. We study nature because she has repeatedly proven herself to have excellent mathematical taste.... This is a reasonable claim, and almost poetic. But the idea that pseudoproblems invented by runofthemill mathematicians are the reason students today aren't motivated to learn calculus or other advanced mathematics seems like a massive overreach.
I'm sympathetic to the author's position. I watched my daughters slog through AP Calculus, solving many abstract problems and many applied problems that had only a thin veneer of reality wrapped around them. As someone who enjoyed puzzles for puzzles' sake, I had enjoyed all of my calculus courses, but it seemed as if my daughters and many of their classmates never felt the sort of motivation that Huygens craved and Leibniz delivered.
I also see many computer science students slog through courses in which they learn to program, apply computational theory to problems, and study the intricate workings of software and hardware systems. Abstract problems are a fine way to learn how to program, but they don't always motivate students to put in a lot of work on challenging material. However, real problems can be too unruly for many settings, though, so simplified, abstract problems are common.
But it's not quite as easy to fix this problem by saying "learn calculus like Huygens: solve real problems!". There are a number of impediments to this being a straightforward solution in practice.
One is the need for domain knowledge. Few, if any, of the students sitting in today's calculus classes have much in common with Huygens, a brilliant natural scientist and inventor who had spent his life investigating hard problems. He brought a wealth of knowledge to his study of mathematics. I'm guessing that Leibniz didn't have to search long to find applications with which Huygens was already familiar and whose solutions he cared about.
Maybe in the old days all math students were learning a lot of science at the same time as they learned math, but that is not always so now. In order to motivate students with real problems, you need real problems from many domains, in hopes of hitting all students' backgrounds and interests. Even then, you may not cover them all. And, even if you do, you need lots of problems for them to practice on.
I think about these problems every day from the perspective of a computer science prof, and I think there are a lot of parallels between motivating math students and motivating CS students. How do I give my students problems from domains they both know something about and are curious enough to learn more about? How do I do that in a room with thirtyfive students with as many different backgrounds? How do I do that in the amount of time I have to develop and extend my course?
Switching to a computer science perspective brings to mind a second impediment to the "solve real problems" mantra. CS education research offers some evidence that using contextladen problems, even from familiar contexts, can make it more difficult for students to solve programming problems. The authors of the linked paper say:
Our results suggest that any advantage conveyed by a familiar context is dominated by other factors, such as the complexity of terminology used in the description, the length of the problem description, and the availability of examples. This suggests that educators should focus on simplicity of language and the development of examples, rather than seeking contexts that may aid in understanding problems.
Using familiar problems to learn new techniques may help motivate students initially, but that may come at other costs. Complexity and confusion can be demotivating.
So, "learn calculus like Huygens" sounds great, but it's not quite so easy to implement in practice. After many years designing and teaching courses, I have a lot of sympathy for the writers of calculus and intro programming textbooks. I also don't think it gets much easier as students advance through the curriculum. Some students are motivated no matter what the instructor does; others need help. The tension between motivation and the hard work needed to master new techniques is always there. Claims that the tension is easy to resolve are usually too glib to be helpful.
The HuygensLeibniz tale really is a cool story, though. You might enjoy it.
(The image above is a sketch of Christiaan Huygens's first pendulum clock, from 1657. Source: Wikipedia.)
I've been reading my way through Frank Chimero's talks online and ran across a great bit on maps and interaction design in What Screens Want. One of the paragraphs made me think about the abstractions that show up in CS courses:
When I realized that, a little light went off in my head: a map's biases do service to one need, but distort everything else. Meaning, they misinform and confuse those with different needs.
CS courses are full of abstractions and models of complex systems. We use examples, often simplified, to expose or emphasize a single facet a system, as a way to help students cut through the complexity. For example, compilers and fullstrength interpreters are complicated programs, so we start with simple interpreters operating over simple languages. Students get their feet wet without drowning in detail.
In the service of trying not to overwhelm students, though, we run the risk of distorting how they think about the parts we left out. Worse, we sometimes distort even their thinking about the part we're focusing on, because they don't see its connections to the more complete picture. There is an art to identifying abstractions, creating examples, and sequencing instruction. Done well, we can minimize the distortions and help students come to understand the whole with small steps and incremental increases in size and complexity.
At least that's what I think on my good days. There are days and even entire semesters when things don't seem to progress as smoothly as I hope or as smoothly as past experience has led me to expect. Those days, I feel like I'm doing violence to an idea when I create an abstraction or adopt a simplifying assumption. Students don't seem to be grokking the terrain, so change the map. We try different problems or work through more examples. It's hard to find the balance sometimes between adding enough to help and not adding so much as to overwhelm.
The best teachers I've encountered know how to approach this challenge. More importantly, they seem to enjoy the challenge. I'm guessing that teachers who don't enjoy it must be frustrated a lot. I enjoy it, and even so there are times when this challenge frustrates me.