Friday, July 11, 2014

Who should I blame?

I have helped many students debug their code. Helping students learn is deeply satisfying to me. But, although I enjoy teaching, I have one pet peeve. It usually goes like this:

Student: "My code won't compile.  I think the compiler is broken."
Me: "Really? What happened?"
Student: "I ran my code, and it just spit out a lot of errors, but I know my code is right."
Me: (looks at compiler error, clicks the first link): "I think this function is supposed to return something"
Student: "....oh."
When there is an error, students will blame the compiler, they blame the starter code, they blame anybody but themselves. This irks me because their logic is so obviously wrong: you have been coding for 1 year, GCC has been around forever. What is the probability that it's really the compiler's fault?

I had a change of perspective on this matter. For the first time in a long time I was using Java to complete an assignment. It was a large, computationally intensive program. I was reimplementing collaborative filtering to run on the Netflix challenge. At some point, I ran my code and got this error:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 at java.util.HashMap.<init>(
 at java.util.LinkedHashMap.<init>(
This seemed like the worst possible news to me. I bemoaned by problem to another student:
Me: "Oh my God! I broke Java.  I used up all its memory."
Student: "Did you tell it you needed extra memory?"
Me: "Huh?"
Student: "Just type -Xms512M -Xmx1024M"
Me: "...oh."
I was so embarrassed. I'd violated my own pet peeve. You would think I'd have my priors set correctly on the error being my fault, not the compiler's.  I started to wonder, maybe it isn't about priors.

Over the next months, I started to note other ways of blaming a system for things that were really my fault:

  • "%^*##%ing CSS! What an idiotic way of designing a system."
  • "WHITESPACE?! Whitespace CANNOT be a bug. Damn you Python!"
  • "Why do I have to tell you to convert this number to a string. I'm printing it! Can't you figure it out!"

This list became long and I read it many times. Although it was painful to admit, I had to draw a conclusion that most of my time spent "fixing" bugs is actually spent swearing at my bugs.

Faced with the aggregate of all my time wasted in frustration, I decided that I had to change. I didn't want to waste my life swearing at a compiler that couldn't hear me. I decided that regardless of whose fault the bugs were, I had the power to change myself, and I did not have the power to change the compiler. With that insight, I realized what was really going on.

  • I want to find bugs in my code.
  • My limitations have caused these bugs.
  • I need to acknowledge my limitations to find my bugs.
  • I don't acknowledge my limitations because it is painful.
  • The only way forward is to change my attitude toward my limitations.  
  • Therefore, I have to want to find my limitations.
This small change in perspective made a world of difference in my debugging. Debugging was now a learning opportunity rather than a swearing opportunity. In a way, this change of perspective make me smarter.  Ironically, in order to become smarter, I had to stop thinking of myself as smart. I had to acknowledge my limitations and face them.

When students are learning, they blame the compiler simply as an act of self-preservation. Gradually relaxing that need is one of the life lessons that computer science teaches us. 

No comments:

Post a Comment