Tuesday, October 02, 2012

Debugging is Good For Learning

I was going to title this post “I love debugging” because, well, I do love debugging code. For me that is one of the most fun puzzle solving mind challenging things someone in computing can do. This is contrary to most people I think. Beginners in their first job often feel that they are “stuck” debugging and cleaning up other people’s code when what they really want to do is write brand new code from scratch. There is where the glory is! Bah!

One of the interesting quotes in computer science is Brian Kernighan saying:

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it

The glory may be in writing original code but the difficult part is debugging. Anyone can write crappy code from scratch but it takes someone with a good brain to clean up other people’s messes. In his essay "Learnable Programming" Bret Victor early on states a truism that I think we tend to forget while teaching students.

Programming is a way of thinking, not a rote skill. Learning about "for" loops is not learning to program, any more than learning about pencils is learning to draw.

Real debugging is more than just looking for the typos and getting the syntax right. Sure that is part of it. Did someone use a “*” where they were supposed to use a “+”? Or is there a semi colon in the wrong place? These are all part of it but only a small part. Debugging requires understanding of what happened, what was supposed to happen, and what sort of things could cause the disparity. It requires understanding of a way of thinking.

We struggle teaching complete beginners because we do have to teach them a big rote skill about what a loop is and the like at the same time we are trying to teach a whole new way of thinking. This is why tools such as Alice and Scratch which avoid a lot of syntax are so popular. They let us focus more attention on the hard part – learning a way of thinking.

Getting back to debugging for a minute. I would argue that the real reason beginners should be fixing other people’s code is that doing so will help them learn more and faster how to think like a programmer. While debugging code one can look at intentions and understand what someone was thinking (or not) when the code was written. Did they take a shortcut they should not have? Did they make some incorrect assumptions? Did they just get careless? Did they forget test cases? What went wrong and how can it be fixed without creating new problems.

That fixing things without creating new problems is harder than most beginners think it is. If you are an experienced programmer you know that already but beginners need to learn that.

I wonder if what students need is to be assigned more “broken code” and be asked to fix it. It may help with the whole learning to think differently that so many struggle with. Thoughts?


Algot Runeman said...

In isolation, fixing someone else's code can become just another rote experience. Wait. It isn't like rote memorization. It is like dreaded homework. If the task isn't creative or fun, it will become just another dull task to get through.

You pegged the issue when you said "puzzle", and it may be that good code analysis or even good code creation is part of the puzzle solving part of a person's thinking process. When approached correctly, solving a puzzle is fun. When approached as drudgery, puzzle solving is a pain.

For many, finishing a large crossword puzzle is more fun than the time spent when the border is done, but the big middle is blank. (Getting the border done is satisfying, but is probably seen as the "easy" phase.) Coding is in the same realm. Coding, though is an encounter with a jigsaw puzzle whose parts seem to fit in that vast center part. The whole thing is done, but some of the middle parts are not quite right.

For those who see debugging as a chore, the center "just about right" is enough. That has been one reason that school administrators have said, "Most kids aren't going to become programmers, so let's not have programming part of everyone's curriculum."

Debugging is part of the same drive that gets a kid to shoot free throws until he can do ten in a row. It is tough to "teach."

Nonetheless, presenting "treasure hunt" opportunities and game-like challenges might be one way to capture a larger group to appreciate the joys of debugging.

There is also no doubt in my mind that the debugging skill isn't limited to programming. Just like the free throw challenge, debugging is a very important life skill. Debugging code is actually a good tool for learning the generic mindset. A fixed program works when it has been debugged. That makes successful debugging easy for both the learner and the mentor (teacher) to assess.

Of course, after debugging, comes the factor of code elegance, a subject for another discussion.

Anonymous said...

I think that debugging is a good skill to have, in general. But I also think that in the context of learning it has to be carefully managed. One challenge is that typical programming environments just aren't tailored to the needs of novice programmers. Here's an artificial example to explain what I mean:

I visit codecademy, which shows me a console with the message, "Hey! Let's get to know each other. What's your name? Type it with quotes around it, like this: "Ryan" and then press enter."

If I leave off the trailing quote, it tells me "SyntaxError: Unexpected EOF" and then "Make sure you enter your name in quotations!" The first error message is probably incomprehensible to a novice (What's syntax? What's EOF? If EOF is unexpected, what *is* expected?) but the second error message is reasonable. Unless I use "smart" quotes: "SyntaxError: Invalid character '\u8220'". (This is unlikely, but it's suggestive: I've used quotes, but they're the wrong kind, and the system just tells me I should do what I thought I just did.) If I use single quotes, everything works fine. So maybe I guess that single and double quotes are interchangeable. But of course they're not.

Most of the compiler error messages I've seen over the years (including messages I've written myself, in compiler coursework) assume that whoever is reading the message knows something about how a compiler works inside. That's a problem for novice programmers. (I'm reminded of work on DEBUGGY, which continues, I think, in the area of cognitive tutoring systems, but I don't know the state of the art today.)