Computer as Brain Metaphor

I have been splitting my reading lately between finite automata and metaphors that shape thought and action. My husband Jonathan and I have an on-going debate about the appropriateness of using the computer as a metaphor for the human brain. I find it useful for describing all sorts of events; he feels it undervalues the capabilities and elegance of the brain.

I probably don't need to pitch my side of the argument to y'all. You've likely said things like...
  • I wish I could install more RAM.
  • Dude, that guy totally overclocked his processor.
  • I can only hold x things in memory.
  • Core dump!


But it bothers Jon, and he takes me to task whenever I say something that betrays my underlying metaphor. I've been trying to understand why we have different emotional stances on this, and I've hit on the following. As a programmer, I think of my computer as the outlet of my creativity, the tool by which I express my craft. A user tends to think of his computer as an annoying appliance that would give him access to all this great stuff (entertainment, social contact, information, pr0n), if it would just freakin' work. You've seen how users treat their laptops: bang, pound, whack! Given how Jon and I view our brains (as valuable, precision tools), I can see why he does not want to think of his brain the way a user thinks of his computer.

Beyond that, I see Jon's side: This metaphor leads you to think of intelligence in terms of processor speed or amount of RAM, which leads you to believe you can quantitatively compare the intelligence of one human to another, and that leads to a very narrow definition of human intelligence. There is more to intelligence than number of instructions per second. To satisfy me, a metaphor for intelligence has to accommodate empathy and personality and intuition. From these spring creativity, and society, and humanity.

At least, that's what the wetware wants me to believe.

Runs in the Family

I'm a language geek, but I try not to be a nit about it. I like the subtle nuances in choosing the "right" word for a situation, but not at the expense of connecting and communicating with real human beings. However, sometimes a small change in word choice can have a large impact on clarity.

In JP's Nothin' But .NET class last week, we had an object called "criteria." (He was creating a DSL for generating SQL statements. Neat stuff.) My brain kept tripping over the example, until I realized, "Oh! Your criteria is a single thing, and I'm expecting it to be a collection. Ah ha!" So I suggested a name-change to "criterion," not to be pedantic (I swear), but just to improve clarity.

A little time passed, and then a student raised the objection I was expecting. "Well, actually, Merriam-Webster's says..." I know this objection well; I've explored it, and I've read Merriam-Webster's editorial philosophy (Did you know your dictionary has an Introduction?). M-W has a descriptive focus, not prescriptive; their intent is to capture and document language usage in the wild. It's a good resource, but not when you want to know the "proper" use of a word.

Knowing this did not improve my image in the class.

Ah, well, I gotta be me. Teasing me, one student said, "Hey, you know so much about dictionaries. Do you have strong opinions on hash tables?" No... that's my dad!

NAnt and LINQ - namespace error

"The type or namespace name 'Linq' does not exist in the namespace 'System' (are you missing an assembly reference?)"

I was getting this error when using a NAnt script to build a project I created in Visual Studio 2008. Turns out to be related to which .NET Framework is targeted, in this case.

Aside: If you are not using NAnt, and you're getting this error when you try to build, then make sure your project has a reference to the System.Core assembly. But if you use the defaults in Visual Studio 2008, then you already have this reference. My project would build through Visual Studio, but not through my NAnt script.

Here's the cause. I thought I should use the latest stable release, instead of the latest beta, so I downloaded NAnt 0.85. It supports multiple frameworks, and by default it targets the framework in use. You can point it to another using the -t command-line argument.

But NAnt 0.85 is aware of frameworks only up to 2.0. For LINQ, you need 3.5, and therefore you need NAnt 0.86 (in beta at the time of this writing). I kept 0.85 just in case, so my NAnt folder contains a folder for each version; they co-exist. I just changed the path in my nant.bat file to point it to 0.86-beta. And voilà.

Hope this helps. Yay, automated builds!

Pretty code: Skeptical of elses

Pretty code is readable code. One strategy for code beautification is to look critically at every if/else statement. Is there a more streamlined way to write that statement? Cultivate a general mistrust of elses.

Some examples...

Testing a boolean to return a boolean

if (x == true)
{
  return true;
}
else
{
  return false;
}

becomes

return x;

If you need to swap those,

return !x;


That's a pattern. Recall that comparison operators (less than, greater than, equal to) return a boolean. So this also applies here:

if (myPropertyToCheck == someValue)
{
  return true;
}
else
{
  return false;
}

becomes

return myPropertyToCheck == someValue;


Guard clauses
You can use a guard clause when you are testing if it is safe to do something, and if not, you want to exit.

if (safeToDoThis)
{
  DoThis();
}
else
{
  return;
}

becomes

if (!safeToDoThis) return;
DoThis();

When the DoThis() is rather involved, guard clauses greatly help the readability for your future teammates (even when that's you). Step 1, check if we're in an okay state, and if not, just get out of there. This saves you from the Hunt The Else game (although, if that matching else is that hard to find, you could break up your method into smaller pieces with more specific responsibilities).

Comparisons
Compare() and CompareTo() methods need to return -1, 1, or 0. It's handy that these are integers, because now you can harness the Power of Arithmetic to do your bidding. Also when you are comparing your own classes, you often want to compare a property that is a value type or a string. Those already have their own CompareTo() methods, which you can borrow.

Say you want to sort your children by their ages. You don't need

if (child1.age < child2.age)
{
  return -1;
}
else if...

(Not just an if/else, but an if/elseif/else. Aaah!) Use instead:

return child1.Age.CompareTo(child2.Age);

If you want to sort them from oldest to youngest, this is where the arithmetic comes in. To flip a negative 1 into a 1, multiply it by negative 1. Same for flipping positive 1 into a negative 1. And zero, conveniently, doesn't mind being multiplied by anything. So you could say:

return -1 * child1.Age.CompareTo(child2.Age);

You can get it even simpler. Because -(-1) = 1, and -(1) = -1, your Compare() method becomes:

return -child1.Age.CompareTo(child2.Age);

Not only no elses, but also no ifs! Very pretty.

Reducing the number of paths through your code (i.e., reducing cyclomatic complexity) gets it closer to being read like prose. Simpler code has fewer bugs, and your successors who have to read your code will think you are smart and good looking. Keep a healthy mistrust of else statements, and write pretty code.