David Bourea

David Boureau

I create web applications

An exceedingly clean code

23 January, 2017

 

Update 9 Feb 2017 : _Today, it is by far my most read article, and also the most hated. I didn’t intend to publish the holy grails of clean code, there is already a whole book for it. As the title implies, the quality is pushed a little too far, and achieve it on every function is probably not so realistic. I tried to explore new ways to make the code more readable, without too much care about performance. You don’t have to agree with / like it :) Take it easy.

 

The article is written with ES6 for examples, but the article could be applied to other programming languages.

 

A small, very small JS function of 11 lines turns into a maintenance nightmare. The slightest bug, the slightest recovery, the slightest refactoring costs a lot of time and energy.

Knowing that any software is counted easily in thousands of lines of code …

Version 0 : do not change anything

And write automated tests. No need to be unit tests written the TDD way. Integration tests written afterwards are just as good enough to begin with. Or acceptance tests.

Without any test, it’s impossible to improve anything.

Voluntarily I do not show the unit tests of this function, the purpose of the article is to give an example of documentation by the code.

Version 1 : Check preconditions

In order to help the reader, while improving the robustness of the code, and to avoid the edge effects, let’s be sure of the input parameters before going further.

We understand what the input parameters are, but that’s hard. Have you noticed the “!” Exclamation mark ?? No ? So why not write some utility functions that makes it great:

And even better, we use an IDE plugin to get a nice alignment

There you go ! No need to comment at this stage, it’s clear as water.

We use Ruby-like code, where each word is placed in the right order to be sure we will able to read the code as in natural language. For example, here one can read in the 2nd line, excluding everything that is not strictly textual:

if proposals is not array of string return []

There you go ! Again, no need to comment until then.

Note 1 : An effective way of fighting the anxiety of “but-what-if-this-happens” (and against the debugging hours!) is to guard against any unexpected parameters by returning an empty value corresponding to expected type. This is the behavior chosen in a majority of cases for lodash / underscore. (For example, returning an empty string if the function returns a String, an empty array if the array must return an Array, etc.).

Note 2 : Even a strongly-typed language wouldn’t have solved all problems. The checks on the difference of the array sizes / on the non-empty array would still have taken place.

Version 2 : Comment by example

Comment the signature of the function. But-that-serves-nothing-if-the-function-is-well-named.

Not exactly.

Version 3 : Verticalize your code

This StackOverflow answer is a good example of verticalization.

In our case, the use of applicative programming make code greater.

Even on a very small function, think about what happens when the flow of instruction looks like this

do thisdo thatlaunch thisdecision pointdecision point

This is particularly painful, isn’t it?

On the other hand, a vertical instruction flow make things much simpler.

do foodo Ado B

Applied to our example, we replace

By this:

We take a breathe! No decision tree, no “unambiguous” variable (item), functions that make a unitary job …

We comments again by example, line by line:

Final Code

Small synthesis