I Don’t Know What X is on Line 48 And I Don’t Care
I was at a users’ group recently here in Chicago, and there were two excellent presenters. There were two very well done presentations: one about Xamarin and one about the C# language entitled “Underestimated C# Language Features” by John Michael Hauck. This was a very polished and appealing talk in which he wove together some important differentiators for the C# language, including closures, anonymous methods, and deferred execution. Given that he’s presented this at some conferences as well, I wasn’t surprised by the high caliber of the presentation.
The format was one in which he presented a series of increasingly difficult problems and asked what different variables were at different points of the program’s execution. For example, here’s something I just made up that would have looked at home in one of his many examples:
public void LetsSeeWhatHappens()
{
int x = 100;
Console.WriteLine(x);
foreach (var f in GetSomeFuncs())
{
x++;
Console.WriteLine(f(++x));
}
Console.WriteLine(x);
}
public IEnumerable> GetSomeFuncs()
{
for (int index = 0; index < 3; index++)
yield return i => index * i;
}
With each example like this, he’d ask the audience what they thought would be the output. And then the fun would begin. There’d always be several different answers and heated disagreement. After all, bragging rights and programmer cred was at stake. This was public gamification at its finest, and it reminded me vaguely of being in a sports bar and listening to people debating heatedly what the next play call would be in the Monday night football game:
Person 1: Third and 7. They have to pass!
Person 2: I think they’re going to call a draw.
Person 3: You’re nuts! That’s stupid! It’ll be a screen pass!
Person 1: Come on, you’ve been wrong every time!!!
I was entertained by this. John was an engaging presenter and the material interested me, but I discovered I had no interest in actually guessing, even to myself, to say nothing of out loud. At one point, a friend of mine that I was sitting with said, “who knows — write a unit test to figure it out,” and I certainly agreed with that point. But that wasn’t it. I think it was just that I was more interested in what the answer would teach me about the language and its nuance than I was in somehow testing myself. Frankly, this seemed like trivia to me and getting the right answer didn’t seem as important as taking the opportunity to hone my critical thinking skills.
Figuring this out, I realized it explained why I was impatient with all of the guessing that people were doing. John would ask people what they thought, and they would guess but then also start explaining their reasoning and arguing with one another. This struck me as boring and inefficient. “Just shut up and let him hit F10, and we’ll have the answer,” I thought. In that moment, I also realized that a very mild pet peeve of mine has always been code reviews or other places where people argue over runtime behavior. I think to myself, “You know what’s better than all of us at being the .NET runtime? The .NET runtime! So let’s ask it.”
After the presentation, I went out for a bite to eat with some friends. There, one of them made an excellent point. When we were discussing the idea of sitting around and figuring out what code did, he said (paraphrased), “if I show code to a handful of competent developers and they can’t agree on what it will do at runtime, then that code needs to be re-written.” I thought this was perfect and couldn’t agree more. The combination of letting the runtime stick to figuring out what things will be at runtime and the idea that well-written code shouldn’t make this a mystery really sort of drove home why this whole exercised seemed to me (and really is) purely an academic thought-drill.
By all means, exercise your brain and solve riddles involving programming. But I don’t think that this type of activity should be the centerpiece of work-place conversations, evaluations of code, or especially interviews. If I’m interviewing people and asking them what X is on line 48, before even the guy who gets it right, I’m going to hire the guy that says, “let’s write a unit test and find out.”
Probably can write a unit test for “What is X after this method runs” but maybe not “What is X on line 48” when line 48 is in the middle of a method. I do agree writing a unit test is a better answer that trying to hand figure out the code. Of course when you are debugging you end up hand figuring out the code instead of just saying “I ran it and got 42”. If you wrote the code and you know you are supposed to get 145 instead then you debug. If you are code reviewing you… Read more »
lol… I like the full moon example, and I’ve encountered a few of those questions over the years. Definitely always fell under the heading of “triva” in my book, and it’s nice to hear that google is gravitating away from this practice. And as for interim locals versus inputs and outputs from a unit testing perspective, you definitely have a good point. I would certainly not endorse writing tests to discover the value of some transitive local variable mid-execution. I skipped a step in how I would actually handle this which would be to test the things that matter (and… Read more »
I think this code would be pretty awful to write a unit test for in its current form. I definitely think “Run it and see.” is a better option on this one.
Especially when you say that you have no idea what the output is going to be. You should be going into a unit test with an idea of what you want out of it.
The console call alone would make a unit test pretty unpleasant to write, I’ll give you that. I took a bit of a leap from that example code to code in general and writing tests as a verification approach. I’m not sure I agree on avoiding unit tests if you don’t know what the code does or should do. Those tests, described by Michael Feathers as “characterization tests” are important tests to write, IMO. They establish the behavior of the legacy code, right or wrong, so you know (1) what it does and (2) if you’ve altered it when you’re… Read more »