Readable code is code that looks like the problem statement
Background
In a recent blog post I showed how you could use Java’s labels as a way to clarify the given, when and then sections of a test. I think that this can result in more readable and comprehensible tests. Obviously since its a matter of style this isn’t an opinion that will be shared by everyone – that’s just natural. Its also good that we can all share different opinions on an approach like that. When my blog post got syndicated on the excellent dzone I noticed a few quite strange comments were made by people.
They didn’t just dislike the approach in question – they disliked the idea of trying to make code read naturally. These counter-points could be broken down into two different groups:
- Developers who didn’t like their Java code to read like English.
- Developers who thought you should try and use Groovy or Scala if you wanted your code to read like English.
I wouldn’t normally take the effort to reply to any old comment on the internet, but I’m of the opinion that this is an important enough topic to comment on. In this blog post I’ll be explaining why I think that no matter what programming language you’re using Readable code is code that looks like the problem statement.
What is Programming?
Programming, coding, hacking – whatever you want to call it – is the subset of Software Engineering that deals with actually writing code. We want to produce a working application that solves some kind of problem. We don’t necessarily know what the problem is when we start – but hopefully our understanding of it will improve along the way. So we’re trying to convince the lump of silicone sitting in front of us that it really wants to solve the problem for us – rather than be converted back into a large sand pit.
The problem is that there’s one heck of a gap between what humans understand and what machine understand. I’m not talking about how cute cats are – what I mean is that there’s a large conceptual impedance mismatch. All CPUs really do is basic arithmetic and logical operations. They can be used to do other things like map the human genome, spread democracy or drive cars but really all we’ve shown is that the computational part of those problems is equivalent to basic arithmetic and logical operations.
A Better Way
Over the past 50 years we’ve been developing programming languages that try to bridge the gap between what the machine does and the problems that we’re trying to solve are. At first this involved providing more abstract machine-oriented constructions – the ability to loop rather than just conditionally branch and the ability to name blobs of code and parameterise them with different arguments.
By the time we hit the 1980s two competing sets of evangelists were trying to tell us to throw away structured programming and embrace abstractions that are orthogonal to machines. Object Oriented programming focussed on the idea that we should structure our code to model real world objects, whilst declarative approaches, such as functional programming, concentrate on telling the computer what to compute and not how to compute it.
Whilst there’s still considerable debate about the merits of these different approaches its pretty clear that everyone wants to try and make the gap between the problem and the machine smaller. The smaller the gap, the less you actually have to program. The simpler they are to write and the easier they are to read. If you have a problem to solve that’s written in a natural language by using the same vocabulary as the problem domain you’re making that gap smaller. If you try and model the operations that exist in the real world – in either functional or object-oriented fashion – you’re making that gap smaller.
Is Java the problem?
Java is a slow to evolve but increasingly multi-paradigm language with excellent developer tooling and widespread library support. No matter whether you love, or loathe it you’re kind of missing the point. The idea that Java is some special case language where you wouldn’t choose to try and write code in a way that reads like the problem isn’t a justifiable case. Its not a special case – its just another programming language. In some capacity or other I’ve been paid to write code in Java, Scala, C, Haskell, R, Javascript, Python, Ruby, Posix Compliant Shell* and even a couple of theorem provers. In all cases the closer your code reads like the problem it solves the easier it is to write and read. Progamming Language matters but some readability concerns are orthogonal.
Neither Perfect nor Correct
We’re all human. We all make mistakes. We all write ugly code. But as an industry we should be looking to try and identify ways to improve ourselves. One principle that I hope we can all get behind is that the more your code looks like the its problem statement, the easier it is to read.
Thanks to Tom Fitzhenry, Martijn Verburg and Daniel Bryant for feedback on this blog post.
* Bash isn’t a programming language – its an embrace-and-extend interpreter.
Reference: | Readable code is code that looks like the problem statement from our JCG partner Richard Warburton at the Insightful Logic blog. |