If you need to introduce someone to functional programming, consider my book, Grokking Simplicity. It’s fun, it’s got lots of exercises, and it starts way earlier than most books on FP do. It’s the book I wanted to recommend to others. I had to write it because it didn’t exist. I think it takes you from functional curious to competent FP practitioner, with none of the theoretical stuff like monads. (BTW, monads are cool, but they’re not as important as the stuff in this book.)
And if you liked Grokking Simplicity, you’ll like my next book, Runnable Specifications. It’s still in progress, but I’m publishing the chapters as I write them. It’s all about software design and domain modeling. Check it out! And tell your friends!
Frontal lobe control loop
I was mentoring someone the other day. We were working through a problem, and when we ran the code, it threw an exception.
My mentee started guessing. “Maybe it’s not n+1
, but n-1
.” He scrolled, placed the cursor, and changed the code. Then he ran it. It didn’t work.
“Hmm. Do I need to get the element at that index?” He changed the code quickly, ran it, and it didn’t work.
I knew he was going in the wrong direction. And he was just guessing—almost panicking. I had seen this behavior before, in my math classroom. When you ask a question like “What’s 12+14?”, kids will often do their best the first time. But if it’s wrong, they start to guess. Not only that, they stop looking at the problem, and start looking at me, the teacher, to see if they’re right. They are trying to solve it like it’s a social problem.
“Woah! Stop! This isn’t a guessing game,” I said. “Let’s stop. Go back to where we were.” I watched him undo a bunch of times, but it was also obvious that he couldn’t even remember where that was. I helped him find it. We reran the code and I saw the error message again. He immediately wanted to fix it.
“Wait! Take a breath. Then tell me what’s happening.” I wanted him focused on the present.
“I tried to access the n+1
’th element of the array but that’s wrong,” he said.
“Woah. There’s a lot of interpretation going on there. Why do you think it’s wrong?”
He gave some explanation about getting an error.
“Okay, that may be what’s going on,” (it wasn’t, but I needed him to relax into the process). “But to find out if it really is what’s going on, we have to look very objectively at what is happening. We need to gather evidence. Tell me, what do you know for sure?”
“I changed the code and it gave me an error when I ran it,” he said. Now we were getting somewhere.
“Good! What can we do to gather more evidence?”
“Um, read the code?”
“Yes. And what about the error message?”
“Oh, I guess that would be useful.”
And so we proceeded.
Just like with my students and the math problem (12+14), if they don’t know how to do it, the process looks like magic. How does the teacher always know the answer? It looks like they’re just saying a number, and it’s always right. Likewise, expert programmers look like they just right correct code most of the time, especially on easy beginner problems.
But we know we don’t. Ask any programmer, of any level, if they always right correct code. Nope. Even on beginner problems, we often get it wrong. We didn’t consider a corner case or we had an off-by-one error. This stuff is hard.
What differentiates a competent programmer from an absolute beginner, in my experience, is the ability to master that first response when you do get it wrong. Error messages are scary. We did something wrong. When we get an answer we don’t expect, we dread the implicit failure of our abilities. Panic sets in. And when we panic, we just can’t think in the way we need to.
The fear response activates a part of our brain that looks for simple pattern matches. Imagine you’re running from a lion through the woods. She’s getting closer. You’re passing trees, rocks, other objects very quickly. You want your brain looking for anything that has a chance of helping so you can act quickly.
But that is not helpful in programming. My mentee was looking for anything that could work. Change n+1
to n-1
(this was primed in his mind because a previous problem had the same pattern). Put square brackets around it to make it do an array access (also primed from a previous problem). Just try stuff because that lion is getting closer!!!!
What we need to learn to do instead is to relax that part of our brains. We need to carefully construct a mental model of what is happening alongside the mental model of what we want to happen. And this is really hard! It takes time. But it starts with that first breath, to help release the tension. Then we can start to focus on what we know.
Over time, as we develop more skill, error messages don’t seem like finger wags or red flags. They’re part of the process—little signals that your mental model is drifting from reality. But this takes a lot of time to develop.
I originally thought this post was going to be about the importance of reading error messages. They are important, for sure, and a good programmer will read them—and also suppress the judgment of how bad the message is—they still contain useful information, and that judgment is just a distraction. (BTW, this might be why many advanced Clojurists don’t seem to listen when people complain about Clojure’s error messages).
But as I wrote this essay, I realized the bigger issue was not a laziness about reading error messages (though I think that’s there, too). No, the bigger issue was how difficult constructing this frontal lobe control loop is, and how tiring it must be maintain such fine control of your nervous system. Perhaps it’s why I feel less than human after a long day of coding. My alert system was full on and I’m suppressing it, favoring my hyper-logical frontal lobe.
I also wonder about the ergonomics of error messages. Apart from the actual text contained in the message, why are they called “errors”? Error means mistake. But if it’s a natural part of the process, maybe it’s not a mistake. Why do we make them red? Is there some gentler way to point out the discrepancy between mental model and code?
Once you can master the frontal lobe, then you can start to refine it. Take smaller steps. Maybe the answer will fall into place with a given/needs analysis. Can you break it down into simpler cases? These skill all require you to avoid the beginner’s panic.
Rock on!
Eric