Readability vs writability

I guess it all started with the massive introduction of high-level languages back in the 50-th. I mean all the clashes between different kinds of readability enthusiasts. Like between COBOL and FORTRAN people.

COBOL version of readability:


FORTRAN version of readability:

E = P * Q
I = I + E

COBOL people state that their code is more readable because it is quite self-explanatory, and the opposer’s code is incomprehensible and meaningless out of its context. FORTRAN guys parry that their code is clean and concise, and the opposer’s is overly verbose and error-prone.

Both have valid points. Both are basically right.

Now Lisp is also generally considered unreadable:

(define (qs xs)
(if (empty? xs)
(list )
(let (
(middle (first xs))
(others (rest xs)))
(let (
(left (filter (lambda (x) (<= x middle)) others))
(right (filter (lambda (x) (> x middle)) others)))
(append (qs left) (cons middle (qs right)))))))

People are pretty much attached to infix syntax in numerical expressions and prefix in functions. This is the way they teach you in school so it should be the most readable, right? Lisp people however consider homogenous syntax a bliss. You gain so much from everything being s-expressions: from the ease of parsing to pretty transparent homoiconicity. Training a bit to read this type of notation pays greatly in return. For the very least you don’t have to care about operator precedence or the order of evaluation any more.

If you think that’s not a big deal, consider this piece of valid C code:

i = i++ + ++i;

It’s very small, it’s valid, yet it’s absolutely unreadable. Literally absolutely, there is no way to read this code correctly, because the order of execution in expressions is undefined, so it can be either i + 3 or i + 2.

Now if you still think braces are evil, have a look at this:

fvariable ci fvariable c fvariable zi fvariable z
: >2? z f@ fdup f* zi f@ fdup f* f+ 4.0e f> ;
: nextr z f@ fdup f* zi f@ fdup f* f- c f@ f+ ;
: nexti z f@ zi f@ f* 2.0e f* ci f@ f+ ;
: pixel c f! ci f! 0e z f! 0e zi f! 150 50 do nextr nexti zi f! z f! >2? if i unloop exit then loop bl ;
: left->right -1.5e 80 0 do fover fover pixel emit 0.026e f+ loop fdrop ;
: top->bottom -1e 40 0 do left->right cr 0.05e f+ loop fdrop ;
top->bottom bye

It’s Mandelbrot Set in GForth. Forth syntax is postfix, so it doesn’t need any braces at all. When Lisp is about building syntax-trees, Forth is about writing the order of execution in plain. It is very unconventional at the first glance, but once again, if you’re willing to invest into training, you will get your benefits.

From all the high-level languages, Forth is the most low-levelable, meaning it’s basically an abstraction building tool over instruction set. You can build very small, very reliable and very fast pieces of software with it. And because of their concision they still be rather readable, although for experienced Forth coders only.

Concision is generally considered a good thing. The less code to read — the more readable it is. APL reaches the ultimate concision:

life←{↑1 ⍵∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵}

This is the game of life in Dyalog APL. The whole game of live in just one line, isn’t it readable as hell? Well, without special training it isn’t. This is a mere iconic example from the Wikipedia, real-life code can get much more trickier.

However, seasoned APL professionals have little trouble reading this code. You might not believe, but it does have very simple syntax. Everything is being evaluated from right to left, no operator preceding there, so syntactically it’s basically an infix Forth.

But the true power of APL comes from its array processing properties. And it works so well with the APL syntax and the APL notion of functions and operators, all the attempts to bring this power to more conventional languages seem like a series of ugly workarounds.

My point is: COBOL professionals think COBOL code is the most readable. FORTRAN professionals think FORTRAN is. Lisp hackers see us all with pity and sorrow for not realizing the opportunities we miss. Forth coders don’t have to see us very often at all, as they have a courtesy of living in their own world. APL programmers are the alien beasts who see all our languages as overly verbose and hideous.

They all have valid points, they are all right.

This brings us to only one possible conclusion. There’s no such thing as universal readability. Readability is not an inherent property of the language, or the style convention. It is the readers’ ability to read it. Like with every natural language: if you write German, you would not expect people without even the slightest training in German to read it. And like with every other language simply following some arbitrary set of rules about how long your sentences should be, or how many lines per page you should print, would not make your text automatically readable.

What makes your text readable, is the effort you put in it multiplied by the skill you acquired by training and practice. The same goes with the code. Not some magical rules about where to put your braces, but the whole sense and purpose you put in every line of your code.

The better you write — the more readable it is.