Writing for Humans vs for Machines

There’s an important difference between programming languages that favor performance and ones that favor human readability.

Optimizing for performance naturally means writing code that a computer can easily understand. Since humans and computers speak different languages, it’s inevitable for speed optimized code to be unreadable to a human programmer.

One common concept is of memory management. The difference is so subtle and yet so big that most programmers go through their career without noticing any difference.

Take a look at strings in the Go programming language:

var name string = "Michael"

After creating a string, you eventually want to do things to it. Sometimes, you want to mutate the string and swap characters at certain indices with others.

Here’s how you would do that in Ruby:

name = "Michael"
name[0] = "N"
puts name
>>> Nichael

Quick and simple.

Here’s how you do that in Go:

var name string = "Michael"
var newName []byte(name)
newName[0] = "N"
var yetAnotherName = string(newName)
fmt.Println("%s", yetAnotherName)

In Go, instead of using a string, you need to use another data structure to perform this operation. As a consequence, you end up with 3 variables where the first two become useless at the end of the operation.

Behind the scenes, Ruby actually does the same thing but the interpreter is designed to do this automatically. Of course, you end up losing performance every time this code is ran. Since unlike Go, Ruby is also interpreted, you end up with programs that end up performing worse in most cases.

But is performance the only thing that matters in programming? What about being able to easily read and digest code that’s been written ten years ago?

The issue with readability is that it’s subjective. Someone who understands memory management and pointers would look at the Go code and immediately understand it while someone who’s more used to reading human text will find the Ruby code more straightforward.

Personally, I find the Go code better because it’s clear that strings aren’t efficient for such a procedure, so, you need to use the proper data structure. If you let the programming language decide what’s best for you, you’ll end up with inefficient code like in Ruby’s case because computers weren’t designed to think.

However, it means that instead of thinking about logic and data, you’ll be spending extra mental energy thinking about lower level details outside of your problem domain. Eventually, you might realize that the performance gained by using a lower level language like Go is costing you developer productivity. In life, nothing is free.