Writing expressive code 7

Posted by caike on October 07, 2009

Software developers read a lot more code than they actually write. An application source code is nothing but a story written using a specific language. It has state and describes behaviour.

Code written once, will be read millions of times. For the most part, it will be read by a compiler who doesn’t really look for anything but correct syntax. Compilers are not into reading stories. They are too busy for that. Just like assembly-line workers, they follow a plan and do exactly what they were told. As soon as they pass things over to the runtime, they are done. On the other hand, we developers are not like that, are we ? No, we are not!

We are software craftsmen. We like to read stories and even get paid to write some every once in a while.

man_reading_book

http://www.flickr.com/photos/dhammza/91435718/

Think about it the next time you hack that magic one-liner in an application. Do you think you will be able to read that code-golf champion piece of code the next time you look at it ? What if it is not you, but someone else reading it ?

“Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live (…) Alternatively, always code and comment in such a way that if someone a few notches junior picks up the code, they will take pleasure in reading and learning from it.” - Ward Cunningham, CodeForTheMaintainer

An example I like to use for expressive code is method parameters in Ruby. Let’s say you want to stay fit and write a method to calculate a body fat percentage. You write the following:

def body_fat_percentage(name, age, height, weight, metric_system)
end

Apparently it looks nice. Let’s see how it could be invoked:

# fred's height in meters and weight in kilograms
body_fat_percentage("fred", 30, 1.82, 90, 1)

# barney's height in feet and weight in pounds
body_fat_percentage("barney", 32, 5, 300, 2)

In order to write those two calls you would probably have to check the right order for the parameters in the method’s signature. Even worse, every time you read that line you would have to check back its signature just to make sure that the last argument determines the metric system or that the third argument is actually the height and not the weight.

That sounds like a pretty boring story to read!

Let’s make this piece of code more expressive:

# fred's height in meters and weight in kilograms
body_fat_percentage("fred", :age => 30, :height => 1.82,
  :weight => 90, :metric_system => MetricSystem::METERS_KG)

# barney's height in feet and weight in pounds
body_fat_percentage("barney", :age => 32, :height => 5,
:weight => 300, :metric_system => MetricSystem::FEET_LB)

All we need to do to the method signature is to replace the standalone arguments for a hash.

def body_fat_percentage(name, params={})
end

From the method body, the values can be accessed using the keys, like params[:age], params[:height], etc.

In a real life situation, this expressiveness would be achieved from writing our expectations as unit tests. We would first write our failing tests as how we wanted our code to look and act like. From that, we would head towards making the tests pass. When all is green, the tests would turn out to be the reference for how to call the method (running and never-obsolete documentation) so there’s no need to go back to the implementation of the method itself to learn how to to use it.

Writing expressive code often means writing more code, but it also means writing better code. It’s not about making things work, it’s about making things right.

Trackbacks

Use this link to trackback from your own site.

Comments

Leave a response

  1. Pedro Pimentel Wed, 07 Oct 2009 18:34:10 PDT

    Cool ! You’ve cited Ward Cunningham ! Almost nobody remember him and he did a lot of cool things!!

    regarding your example, I usually follow the same approach if the method needs more than 2 arguments, but always there are exceptions!
    ;)

  2. Marcelo Bruckner Thu, 08 Oct 2009 08:49:06 PDT

    Fala Caike,

    Esse assunto já falamos várias vezes… e sempre que posso enfatizo com quem eu converso.
    Interessantíssimo o post, com bom exemplo…

    Abraço

  3. PotHix Fri, 09 Oct 2009 00:59:39 PDT

    Æ!!

    Muito legal o post! Nada como um código legível e de fácil compreendimento! :D

    O exemplo dos parametros foi muito útil para exemplificar exatamente o problema da legibilidade de código!

    Há braços

  4. Paulo Igor Tue, 03 Nov 2009 15:41:17 PST

    Fala Caike,

    Show esse post, falo sempre disso nos Dojos e o pessoal ta cada dia mais preocupado com a legibilidade do que é escrito, criar essa massa crítica e esses adeptos de fazer direito e não simplesmente fazer…é muito bom!

    Vou dar a dica do seu post pra galera.

    Abraço,

  5. Marcelo Lobo Thu, 05 Nov 2009 16:18:18 PST

    Excelente post, parabéns! Mas legibilidade e produtividade é algo que existe a muito tempo em Python. Essa é sua principal característica. O problema é a barreira da quebra dos paradigmas atuais de desenvolvimento. Infelizmente, a academia (e algumas empresas) ‘engessa’ os alunos com linguagens ‘do momento’ não se importando com a produtividade e a portabilidade necessária para grandes projetos, impedindo que conheçam outros horizontes.

  6. Henrique Bastos Thu, 24 Dec 2009 08:06:58 PST

    I want to write great posts just like this, when I grow up!

    []’s, HB!

  7. Francisco Souza Thu, 24 Dec 2009 08:43:06 PST

    Great post, congratulations :)

    As HB, when I grow up, I want to write grat posts too =P

    ;)

Comments

Anti-Spam Protection by WP-SpamFree