Monday, October 05, 2009

Readable code is not for maintenance only

Emphasis is often put on writing readable code, for the sake of maintenance. But you forget and reread code every minute, not in 2016, so why worrying about the far future when you should worry about tomorrow?

Long term maintenance issues
Even your code, after six months, becomes a stranger to you. Especially if you have improved your coding skills meanwhile, the implementation will be very hard to grasp at a glance. While it can be possible and recommendable to study and remember a software system's big picture, code at the low level inside public and private methods it's quickly forgotten: variable names and the general flow have to be analyzed again and again. To put is simply the human mind does not have the capability of memorizing every single line of code and implementation decision.
Though, there are some things a developer usually masters in his mind:
  • The general design of the system, as most new features require a knowledge of it to know which component should accomodate new classes and functions.
  • The Api of a widely utilized subsystems or class, like Zend_Form in php or the Collection interface in Java.
These are elements of the implementation which do not change very often, and that are refreshed in the developer's memory nearly every day. Usually there is powerful documentation on these arguments, but having a mental understanding of them is always more beneficial.
For the rest of the project, a typical programmer has only a mental model of how the entire system works, abstracted away from details like methods signatures and Uml sequence diagrams.
This is not a bad thing: human memory is less stressed and the code becomes the last, most refined step of the design. There is no need to study or document the details if the code is well written, and they change so often that keeping memory or documents in synchronization with the code is likely to be impossible. That's why Api documentation is automatically generated nowadays.
In this vision, encapsulation and decoupling are very important from the maintenance point of view not only for the isolation of changes in the code, but also for the use of developers time. If adding a feature or fixing a bug requires the analization of two or three classes, the developer will finish the job earlier than having to modify method signatures over a dozen of them. OCP strives for only adding new code, but you probably still have to read the old one even if you do not modify it: to subclass, to write a new implementation or to override a method you must know the original signatures and contract.
Moreover, meaningful variables, methods and parameters names aid the developer who has to deal with the code in his forced rapid study of the business logic. Everything you cannot remember has to be learned again and again and the faster this relearning process is, the faster the overall development will be.

Short term development issues
The trouble with the current readable code tips is the starting reason: helping maintainers because six months from now you will have forgotten everything about what you have written today. But if you shorten the time interval, the productivity boost given by readable and well-factored code is still valid: all the advantages discussed for maintenance can be applied in development as well, since maintenance is only deferred development.
No feature is integrated in a single pass: this is particulary stressed in the iteration-based methodologies, but it applies to many low level coding activities. TDD, for instance, prescribes to add a test at the time for the class under development, and to make it pass before repeating the cycle. Being the testing automatic or manual, I bet you start from a simplification of the feature and then refine the details: when you build a blog, first you add the article publishing form, then the visualization of posts, the search, a comment system. You can refine even further by adding new fields to the article model: date and time, tags, author. The process involves going back on the same code continuosly.
What activities do you carry out when making a new test pass? What do you do every single time before writing a single line of code?
You go back to the class you're writing and read again the code you have written yesterday, or two minutes ago to pass the test before. And if you do not have a photographic memory, you don't remember every character you wrote. You have to read it. The majority of the software developers in the world neither have such a memory.
Starting to write descriptive code helps your productivity now. If you do not believe it, try to program some serious application in assembly using (computer) memory addresses instead of variable names. You'll find yourself going back and forth in the source to copy addresses as if they were bad chosen variable names, confusing them continuosly.

Code is written one time, and then it is refactored or rewritten, which I see as a new writing process. It is read thousands of times instead. So what you focus on? Code that is short to write with three-characters identifiers or code that is simple to read?

What does the code in the picture do? I don't know. Even if I wrote it yesterday.


Gigi said...

tipycal => typical

Anonymous said...

+1 Gigi

Anonymous said...

You would probably like The Little Manual of API design

Giorgio said...

@Benjamin: I've already read it some months ago, and I liked it. :) My favourite text on this subject is "Practical API Design: Confessions of a Java Framework Architect", which goes well beyond everything a developer needs to know about designing a good library.
@Gigi: thanks for finding the typo.

fsilber said...

Unfortunately, there are all too many programmers with better than optimal short-term memories. They can remember the contents of a dozen poorly named variables and methods while reading a five page program. In fact, if they've developed prodigious memories to compensate for being slow readers, they might even prefer variable names that are short and ambiguous over names that are explicit but long.

Unfortunately, the profession provides no way to punish them for being like that; indeed, they're often rewarded for their ability to churn out pages of code quickly.

Giorgio said...

@fsilber: I dream that static analysis of code will one day be able to stop commits of bad code... For short identifiers and violated standards it can already. :)