Aug 31, 2012

The simple function call

In his post, “The Plain Old Function Call,” Vinicius Gomes compares these two lines of code:

# version 1
choose('color', ['red', 'black', 'green'], 'ie7')

# version 2
choose('color').from('red', 'black', 'green').ignore('ie7').any

In Python, at least, you can always provide names for your parameters, so we can rewrite his first idea:

# version 1b
choose('color', from=['red', 'black', 'green'], ignore='ie7')

Gomes’ argument is that version 2 reads better, but I don’t see it. Version 1b has the square brackets, but version 2 has extra parentheses. Version 2 also has the weird .any at the end (I’m actually not sure what it’s supposed to do or indicate).

So I dispute Gomes’ first premise: I find it hard to believe version 2 is significantly more readable than version 1b.

But this just avoids his larger point: that we shouldn’t sacrifice readability for ease-of-implementation. Anyone who’s familiar with my work knows I heartily agree — this is the slogan of my own web framework, web.py. But I think Gomes (and the larger tradition in which he writes) has a problematically narrow view of readability.

Take this bit of Perl poetry:

my $dear = "friends" .  
while (<i am gone>) {}  
do { $give_me_a_call=  
"on";  
my $cell = "+00 0000000000";  

The poem is perfectly intelligible as English; it’s just some standard English phrases with some very weird punctuation. Reading it as an English document reveals:

my dear friends  
while i am gone  
do give me a call  
on  
my cell +00 0000000000

But it’s not English; it’s Perl. And reading it as Perl reveals utter nonsense. Take just the first line:

set the variable "dear" to the string "friends"

This doesn’t mean anything (the variable isn’t used elsewhere in the program); it’s purely there because it looks good to English speakers. But this isn’t English; it’s Perl.

A good programmer does not simply read the code as English. They build a model of it in their head and try to figure out what it’s doing. That’s impossible to do with this bit of Perl, because what it’s doing is not at all the same as what it’s saying.

And the same is true of Gomes’ version 2: What is the object choose is returning? And from? To understand the code, you need to know the implementation details of choose — and, as Gomes admits, the implentation details of choose in version 2 are unusual and difficult. How does forcing someone reading the code to understand unusual and difficult things make the code easier to maintain?

Compare this to a sample of web.py code:

class hello:
    def GET(self, name="world"):
        return 'Hello, ' + name + '!'

This code here is perfectly easy to read — but as Python, not as English. We’re creating a class with a method (GET) with an optional argument (name). What it says in English is exactly the same as what it says in Python. Gomes claims his version 2 “requires less mental mapping between the computational representation and the real world thing.” I don’t think that’s true there, but it’s certainly true here.

Rob Pike tells a story from when pairing with Ken Thompson. When they hit a bug, Rob would dig into the code, “examining stack traces, sticking in print statements, invoking a debugger, and so on. But Ken would just stand and think” for a bit, before announcing “I know what’s wrong.”

Ken was building a mental model of the code and when something broke it was an error in the model. By thinking about how that problem could happen, he’d intuit where the model was wrong or where our code must not be satisfying the model.

I’m with Ken — I don’t think you can be a great programmer unless you can build a model of the software in your head. But this is precisely what today’s magical frameworks make it so hard to do. It’s next to impossible to build a model in your head of how a Rails program works — Rails calls random pieces of code at random times while doing all sorts of different things behind the scenes. The result is code that reads very well — but as English, not as code. If you try to understand what it’s doing, rather than just what it says, it’s next to impossible without some very deep engagement with the Rails internals. Under those conditions, you’re not a programmer — you’re a prisoner.

Blog comments powered by Disqus.

About
A quoteblog by Aaron Swartz. You can subscribe via RSS.