A Pact With the Devil: What I Learned from Clean Code

A Pact With the Devil: What I Learned from Clean Code

You may hate him, you may love him, but it's unlikely you never heard of him. Such is the destiny of polarizing characters like Uncle Bob, alias Robert C. Martin: programmer, speaker, and teacher in the ways of Agile and Object Oriented Programming. His fame already preceded the man when I read Clean Code, one of its most famous books, eager to find out about the crown jewel of this author and become an unstoppable dev.

I was barely moving my first steps in IT when I read - no, devoured - this book in under 2 days. I was inexperienced, naive, and desperately needed a spirit guide to face challenging solo projects. I was Faust and he Mephistopheles, sealing a deal to prevail in the unforgiving world of consultancy.

A Double-Edged Sword

In hindsight, this precocious exposure to his ideas was a double-edged sword. I certainly gained an instant boost in proficiency, coding hygiene, and mental clarity. I became a software crusader in the name of Uncle Bob: nasty bugs started to have less fertile soil to grow in the nook and crannies of some logical conundrum, ugly code was ruthlessly purged, and unreadable classes were chastised until they conformed to my paragon of purity. Or, at least, that was how I felt: what a great time!

On the other hand, being exposed to the energetic prose of Clean Code so early led me to hold the book's prescriptions a little too dear sometimes. Even to this day, I feel instinctively surprised when meeting uninitiated developers who for any reason don't share the same perspective as me. Which is great, since that would lead to pretty dull exchanges. However, I feel compelled to share and even promote some of the teachings from the book, which proved extremely beneficial to me even when not followed by the letter. To make things spicier, I will begin with a pretty agreeable principle, continue with a controversial opinion, and end with an outrageous idea from the book.

Naming Things

A commonly accepted piece of advice from Clean Code is that variable and function names should be simple, descriptive, and coherent with their usage. While too much verbosity is not welcome, names shouldn't be unnecessarily abbreviated or vague: a function named updateCAdd could literally do anything, while updateCompanyAddress it's to the point, clear, and boring. Boring is good, as surprises are not welcome when coding.

This chapter becomes especially interesting as Martin becomes a bit romantic. He argues that programs are written in pseudo-English for a reason, as their logical flow should unfold naturally for the reader. Code should tell a story about what is happening and who is doing it, a narrative that doesn't leave room to interpretations or ambiguity: parse a JSON, then add a user, get the order's information, and finally send a mail. A developer's story should be soothing and predictable, like grandma re-telling the same old bedtime story for the tenth time.

Of course, Uncle Bob is a histrionic character that loves holding speeches and writing books, so he probably sees everything as a story just waiting to be told. Nonetheless, his point about good naming practices still stands, as we all know about the famous quote from Phil Karlton: «There are only two hard things in Computer Science: cache invalidation and naming things». And let's be honest, most of us have to deal daily with just one of these.

Robert C. Martin
Robert C. Martin posing as Uncle Bob. He is quite the character. Source: https://sites.google.com/site/unclebobconsultingllc

Comments Always Lie

I am afraid the animosity of Bob Martin against comments does not find equally wide support in the community. The crux of his argument is that "comments always lie": if it's not straight away, it'll be as soon as the block of code being described is refactored. The older the comment, the worse it holds as time goes on and code around it changes, is moved around, and gets buggy. Instead, Uncle Bob suggests adhering to a descriptive naming habit that makes unnecessary use of comments, as mentioned in the previous paragraph. Consider the following function signature in Go:

// Creates an invoice from its data and sends it to the specified client. 
// It will return an error if the operation fails.
func SendData(data *Data) err {
  ...
}

We can easily get rid of the comment by splitting the function into 2 parts and renaming a couple of arguments:

func CreateInvoice(invoiceData *Data) (*Invoice, err) {
  ...
}

func Send(invoice *Invoice) err {
  ...
}

I think we can agree on the fact that the final version has no comments but is way more readable.

On the other hand, I saw places where a brief comment is not that bad. Uncle Bob speaks about an ideal state of clean, beautiful code: the reality is that we need to produce working programs in a reasonable timeframe, we are not monks carefully composing mandalas. Sometimes a short comment can shed a lot of light on an otherwise obscure operation. We can advise not deleting an apparently superfluous check, and we can reference some edge use cases that may need special attention in the future. Martin would scoff in disapproval, but as practitioners, we shouldn't deal in absolutes like Siths do.

Chinese Boxes

One of the most surprising opinions held in this book is about the ideal length of any function: about 3 lines! To explain his point, Martin tells a personal story: it seems that a long time before he wrote the book he visited a friend of his, one of the most talented coders he ever met. In that afternoon, this formidable engineer showed Martin a cute desktop app that added to the mouse cursor colorful sprinkles as it moved over the screen. Martin, while entertained for a short while, inevitably asked to give a look at the code, maybe to secretly appraise its cleanliness. He was absolutely delighted to constatare that his friend was strictly sticking to a peculiar rule: any function should be either 3 lines long or refactored in smaller subroutines.

According to Uncle Bob,  any program should resemble a game of Chinese boxes, gradually descending from one level of abstraction to the other. The benefits of this Mandelbrotian design allegedly are the separation of different abstraction layers and code that can intuitively be understood with a glance. Extended refactoring also helps in removing redundant code and in creating reusable modules.

There are good intentions behind the 3-lines rule, but I refuse to consider it seriously, or my sleep would be tainted by recurrent fever dreams about fractal geometries. Instead, I simply appreciate code that separates business concepts and low-level operations and doesn't put hundreds of lines between the same pair of curly braces.

Conclusion

One can't take to heart all the prescriptions of this book, or they would halt the majority of PRs at their company in a cult-like frenzy. However, keeping in mind these rules helps in making sensible decisions when developing, like when the produced code starts to become too confusing and should be refactored.

What is your take on Uncle Bos's teachings? Do you have any unpopular opinion about what good code should be? Let me know in the comments!