Superpower
Let's face it, us developers live in a very strange world. Explain what you do to 95% of the population and they'll likely glaze over before you've finished your sentence. What you do with a computer day-to-day looks like bloody wizardry to most people, and so it should, programming is a superpower.
It is a superpower that needs careful thought and consideration, particularly for those programmers who are going to have to read your code later.
Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.
The one book I wish every programmer before me had read before writing that 3000 line function is Clean Code - Robert C. Martin.
Why Clean Code
This book gave me a whole new perspective, it has restructured the way I think about each line of code. It made me realise that there is an art to being a software engineer.
It teaches:
- How to identify bad code
- How to meaningfully name variables/classes/functions
- How to write clean, small, single-purpose functions
- When to comment, or rather, when not to comment
- Guidelines to formatting code properly
- Using objects and data structures for appropriate data abstraction
- How to properly follow the laws of TDD and write clean tests
- Elegant ways to handle errors
- Endless refactoring tips
- 67 smells and heuristics (Yes, I counted.🤣)
And much, much more.
Whenever I'm programming I have Clean Code an arms reach away as a reference. The book has tonnes of examples of transforming bad code to clean code and the step by step process on how to get there.
For instance, just the other day I was refactoring a function which violated the single responsibility principle on numerous counts and was scratching my head on how to split it up properly. I consulted the book to jog my memory on an efficient way to get about the process and there was an example exactly like my problem, the only minor difference really being the context.
Uncle Bob
Robert C. Martin (Commonly known as Uncle Bob) is a programming superstar. Not only does he write absolutely brilliant books he is also a very talented speaker. Just YouTube "Uncle Bob" and you'll find a stream of talks he's done, each of them as interesting as the next.
His blog is also one of my favourites to read with some pretty accurate quotes:
Finally
In my opinion, every programmer should read this book, at least 3 times 😄. It'll give you a whole new love for programming. You'll actually begin to understand when you're writing bad code. You'll look at your old code and wince at its structure, the vertical spacing, the complexity, the out of sync abstractions, the useless comments, and the spaghetti nature. (well, I do, every-single-day). In the book, the code snippets are in Java but the same rules apply to most languages!
This blog is only a brief introduction to the benefits of reading this book, I strongly recommend you have a read if you haven't already. I'd love to hear your thoughts on Clean Code and potentially how it changed your perspective. I'd also love to hear of some other books which have completely altered the way you look at code.
Follow me on twitter if you don't want to miss out on absolutely brilliant programming insight: 🤣 @luke_garrigan
Top comments (66)
I don't know. Uncle Bob has some good things to say (e.g. SOLID), but he's also spawned a few bad ideas, too, like this...
To me, that alone shows that Robert Martin has forgotten what it's like to jump cold into someone else's code, especially code using languages, tools, or concepts he isn't familiar with. And anytime someone is so lost in their own expertise, they forget what it's like to NOT be an expert, I have to call literally everything else they have to say into question.
In my experience, comments should generally express the WHY (intent) of the code. That's necessary quite often because even the best written code can NEVER express its programmer's intentions. The WHAT is obvious, but the WHY is often inexpressible in machine logic.
To Comment Or Not To Comment?
Jason C. McDonald ・ Jan 20 '19
Besides that, even an extreme absolutist "best practice" declarations like "comments are always failures" show a contemptible sort of arrogance. That sort of statement reads as "My expertise is so vast, it accounts for every conceivable situation and exception. I have nothing more to learn."
Even following his doctrine religiously cannot yield perfect code. There is no "one size fits all" solution.
Clean, DRY, SOLID Spaghetti
Jason C. McDonald ・ Jul 24 '18
But then, I've always found that Robert Martin just tends to be unable to distinguish his opinion from objective fact, and he's given to believing his own press releases. Ego precludes trustworthiness in my experience, and on that basis, I recommend looking to less egotistical sources for programming practice. Even if Martin coined some of these otherwise brilliant concepts, I'd rather they be (re)taught by someone who vetted them in practicality and humility.
I guess this is just opinion-based, I'll be honest I partly agree with his statement. I would much rather jump into code and see intent expressed through variable/function/class names. In the book, he actually goes on to talk about the appropriate times to use comments.
I don't agree with this, if done properly code can absolutely express the programmers intent, pretty much the entire purpose of learning to write clean code. What Grady Booch said springs to mind:
Well, I think it's a point worth discussing (maybe elsewhere? It's bound to get long). All I know is, intent-commenting has always yielded vast returns for me and my company.
It has reduced "onboarding time", especially for beginners.
It highlights logic errors, which are caught sooner.
It reduces code review time.
It reduces the time spent picking up one's own older code by at least half, usually more IME.
None of the above precludes clean coding principles (aside from comments). You never need a comment to see what the code is doing by itself or in direct context...only why it's there, in the grand, fully-abstracted picture.
It may come down to one's definition of "intent," but based on clear and measurable results, clearly Uncle Bob missed something.
And that's my main point. Robert Martin stated an absolute as if it were utterly impossible for him to be wrong in any case, and yet I can point to many cases where he literally was. The main issue is, Martin regularly confuses his opinion with objective fact.
That sort of absolutism is why I trust nothing coming directly from Martin; only once it has been vetted by programmers who combine experience with humility, will I consider it something of merit. (I learned many Clean Code principles this way, and I follow them.)
Well I do kinda find the absolutist style a little jarring myself. Yet I am largely skeptical about anything that I cannot related to person experience. I am also aware that I have some of the same tendencies to declare things as absolutes based on my own personal experiences.
In the case of comments, I believe that there is/was a school of thinking that comments are good, so more is better, and maximum is best, so folks would slap a giant comment in a big banner over every tiny method. I literally had a college supervisor who did that himself and taught it as best practice. Comments would say obvious stuff so you stopped reading them and often they were out of date, misleading or vague.
This means that when I first read the book it was a lightbulb. It was literally telling me something my college supervisor did wasn't a good idea. I had kinda figured it out but I still would have said comments were mandatory as that was what I was taught.
It depends on the language, the task, the team, and the context what is appropriate. If I am writing for my main day job I aim to write brutally simple and obvious code. I spent a significant amount of time to reread my code and mentally explain it to an imaginary third person with no experience. I picked this up from joining a large team where we would have to do a show-and-tell of code we wrote that was a new feature. It was done in the large team to share knowledge on a global call. We tended to practice presenting before hand as it was embarrassing when someone was trying to talk about their code and it was a trains smash. Often someone in the audience would ask about a specific block of code and the presenter who recently wrote it would stumble to explaining it. When rehearsing whenever I would stumble I would refactor my code to rename classes, methods and variables. The renaming was always to better express the intent of the code.
Time permitting I always rehearse presenting my code as I read through it even if I never present it. As I do this I refactor my code to be as obvious as possible. Sometimes due to time or just complexity of the situation I cannot make the code clearer. So I slap a comment on it. This always feels like is a small defeat.
Well, and see, the commenting style I'm advocating (read the article I posted) doesn't conflict with this. It should always be obvious what your code is doing.
That's not what I mean by "intent". For example, the best clean code will show you that you're looping through all the entries in your "clients" dictionary and uppercasing the first letter of the name, but it may not be clear you are "correcting name capitalization issues"...or if said intent is obvious, it might not be so until you read and ponder 3-7 lines of code for a bit. That's wasted time.
(Pedantic Note: Yeeeeeees, the above example could be wrapped in a function called "fixNameCapIssues()"...I'm referring to sections of code that cannot be abstracted out. In practice, that's most.
Intent commenting is actually a living specification. You know that old rule about "don't code without a spec"? Put the spec in comment form, and code within.
I'm not the first to pioneer this. Donald Knuth created an earlier (and much clunkier) approach called Literate Programming.
If your comments simply describe what your code is doing, you should refactor so the code's function and purpose is obvious, but you should include a comment describing the language-agnostic intent of the logical section of code.
Make more sense?
(Read my article I posted earlier in thread about this for a more in-depth explanation, if that still doesn't make sense.)
Thanks for the link but that style of documenting isn’t something I would do in my context. I concede that If I joined your team I might discover that first over commenting and then removing the obvious comments might be optional in your context.
I am curious whether you do TDD. Writing tests to express intent and check the code meets it is something done in my context. That goes beyond self-documenting code. Code reviews expect a test suite as specification and that it is clean code with self documented intent.
And that's fine. I don't expect my take to work for everyone, everywhere, every time (unlike Robert Martin). I've yet to personally encounter someone who tried it and didn't benefit, but I've also yet to encounter a majority of programmers. ;)
Of course! Testing and CI is critical to our workflow. However, I've also found that testing, by nature, can replicate none of the benefits of intent-commenting.
In my experience, the best code is...
In all my years of coding, I've never found any one of those items to be replaceable by any combination of the others.
Of course...
YMMV, and
If you're not working as part of a team, it may be hard to impossible to observe the negative impact(s) omitting one of the above might be causing. (e.g. you may not need to write a spec; you keep it all in your head...until you have another developer.)
that's very well said. thanks.
There is an unresolvable paradox here. I agree that if you want to read code like prose, it must consist of abstractions. Otherwise the nitty-gritty details would have to be exposed. But remember, abstractions likely take you away from the "direct" and "straightforward".
It's one more level in your mental stack to balance. The question lingers in your head, ok, what does it actually do in this case?
Often, abstractions can't be made "crisp", they are rather leaky.
Abstractions (aka how to partition concepts, where to draw lines) are hard to get right the first time. You need a good few iterations on them to begin with.
Even a good partitioning of concepts can be ruined later, when a new kind of edge-case needs to be handled. A tiny detail changes, the whole design needs to be revised. In reality, the tiny edge-case is often addressed at a place it doesn't really belong, making the nice prose lie.
Not complaining, just noting. Don't be shy of exposing details if that makes sense. Start to abstract one you see a pattern recur 3-5 times and have a good grasp on the various edge cases. Always be wary.
Code has a nasty little tendency to be paradoxical, doesn't it? XD
"Clean coding" principles always require careful thought; Clean, DRY, SOLID Spaghetti is still spaghetti. :P
The problem is that even if you write perfectly you have to consider different people reading your code as well and what you find clear I might find confusing and vice versa. I comment, not for me or people that read code like me, but for people that read code differently.
Basically it's like explaining things that I know is not general knowledge or common practise. Like I would do when writing any text.
It's like When Max Thunberg, a friend of mine, is to read my code. Well, not really, just wrote that sentence to demonstrate that while I and people around me know who I meant I had to comment on who Max is to clarify for others. The same could be true when, as an example, I'd call an API. If I used an unconventional way to save memory I'd also comment on why I didn't follow conventions.
Another reason is to speed up on boarding of junior developers or just developers coming from other languages.
Yet another reason could be to help none coders, like customers, understand the code.
Lastly I have dyslexia and for me comments makes code more readable even when I don't read them simply by breaking up the code, giving me visual anchors.
So,while I agree with the notion that comments are failures to express ourself clearly enough through code I also believe that to be an impossible task.
This could be a nice code challenge, to take a piece of commented code and refactoring it without comments in a way that's more clear and then discuss the different solutions.
This is such a valuable view! Inclusiveness is so important for designers, but we developers forget it. Everybody must be as good as us, our code should tell everything. But someone with dyslexia, or someone not proficient in English, or even beginners will have a hard time if we do not take them into consideration
Code cannot express things external to code, such as - implicit assumptions about input data, performance considerations, all the background theory and extensive research put into the resulting optimised algorithm, experimental results (such as performance measurements) taken into account, and so on.
I believe in the very opposite approach - Literate Programming. You must have more comments than code, because code is the easy part, all the background thought trail is hard and must be recorded. No way you'll put it in your variable names.
A good quote to live by when it comes to commenting and writing clear code comes from, I belive, a programmer by the name of John Woods. While it originates from the early 90s it's still a creed I live by:
He is right about the comments. The only times you can't understand the code is either if the code is unreadable or you're a novice programmer. Bob Martin teaches you to write code that is readable, to write it in small, isolated modules that are understandable on their own. If you understand those pieces individually (which you will), then you will understand the whole. You will not need comments, even for a new code base, if the code is written with SOLID principles (which it rarely is). The only exception (and he talks about it in the book) is if something cannot be made clear with code, then it makes sense to use the comments. A recent example I had at work comes to mind: a 3rd party library we're using required us to extend a class and provide a method, which had to have a certain very unfortunate name, and I clarified as a comment the cases when the method will be called. Any other comment I encounter at work is either outdated or misleading. Worst comments are of sort "don't touch this because X". First thing to refactor is to remove those comments.
Wrong, wrong and wrong. Code cannot possibly contain all the necessary information - even with very elaborate naming, you still leave all the background behind. Code does not answer the question "why?" - only "how".
You might want to have an architecture documentation, but comments is not a good medium to explain "why". If you have to explain "why" in the comments, it's akin "we need this for X" comment with an intent to prevent you from refactoring, which is unacceptable. Code should and could express a clear intent and need not comments. As I said, if the code is clear, every piece of your code is an isolated module, and if you understand every module in isolation, you will understand the whole.
No, I do not want a separate architecture documentation. This information is essential for understanding the code, and as such must be always visible alongside the code. That's why Literate Programming is the right way to go.
Code simply cannot express all the complexity behind "why". Absolutely. Impossible. Full stop.
Comments can't do it either, as comments is a textual representation and suffers the same linear limitation as code. Your documentation will need diagrams, connections, connected graph nodes that span multiple modules. It's not feasible to write this kind of documentation in the comments, because comments are tied to a particular module / part of the module as opposed to being able to span multiple modules, and, again, because comments are textual, not visual diagrams.
Thanks for letting me know about Literate Programming, I checked it out and it looks like the worst possible way to write code with the worst possible duplication, which will slow down the developer to at least a half of their normal speed (probably way more in practice).
By the way, notice how you didn't give any reasoning or rebuttal of my points, and until you do, there's nothing further to discuss.
You sound like a zealot - and that's why I said earlier that anyone who took this pathetic "clean code" religion too seriously is lost forever.
Of course I did give you a lot of reasons, but you evidently cannot get them, since you're perceiving everything through your religion.
Let me reiterate it once more:
1) Code per se is the easiest and the least important part of the story. What really matter is how you got there - all the background work that ended up in this code. It can easily be an order of magnitude more information than you'll find in the code itself - all the theory you had to derive before you'll even start thinking of architecture, all the experiments you had to conduct and record, all the assumptions you're making about the data, about performance requirements, etc. - it's all very relevant to the code, but cannot be expressed as a code.
You're right, plain text is a very poor media, and that's why I keep talking about Literate Programming - it allows to express pretty much anything. Take a look at any of the good examples - e.g., TeX and Metafont.
2) I have no idea what you're talking about here. There is no "duplication" whatsoever. In a literate code you have both "why?" part of the story and "how?", perfectly tied together. And if you're churning out code at maximum typing speed, I'm pretty sure you're doing it wrong and you're extremely inefficient. Code should be the least of your concerns, and writing code should take a tiny proportion of your time.
Of course, if all you do is some CRUD that nobody cared to automate yet, it'd be a different story for you, and it's understandable if you swear by all this "clean code" religion, but if you do anything even marginally more meaningful than that, "clean code" is a pile of crap.
Thanks for a good chuckle. Read your own comment with fresh eyes and tell me, who sounds more like a zealot?
Before you start designing architecture, there's a requirements gathering stage, which is done via Jira or something like it
You have version control for that
You can write tests and your "experiments" are forever recorded and actually validate your code
You can use interfaces for that
You can write performance tests as well
Interesting. Well then, I'll leave you to writing TeX for your programming. I'll keep using reasonable methods.
You just proved my point that it slows you down. If I were to write only code, it would be a "tiny" fraction of what you spend writing all the "why" stuff.
Okay, I know what you mean, you should always design your code before you write it, and it's fair. Designing and writing code is a process that happens all the time, you design, write, realize there's more intricacies, then design again, write, realize there's more intricacies, etc, until you finally arrive at the code where all intricacies are addressed to achieve current requirements. This process does not need to be documented and nobody in their sane mind would ever record this process, and nobody in sane mind would ever need to know how you arrived at it, they just need a final result so that they can contribute to the code via the same process. And, the only requirement, to my mind, is that the final result is readable and maintainable, then the software product can survive and thrive.
Have you actually read Clean Code? Where do you get the idea that CRUD has to do with it? In my experience, Bob Martin's way of writing code actually goes against the way the development is often done for CRUD. For example, a lot of times it's done in a Controller -> Service -> Repository way, and, Clean Code actually frees you from this pattern and lets you focus on the requirements and clarity of the code as opposed to adhering to a certain pattern.
Nope. Not really. Long after you have a clear idea of the requirements, and long before you can even start thinking of the architecture, you need to burn through quite a bit of theory. This can be heavily mathematical (good luck representing all this math in plain text, or, worse, in code), or probably it will require quite a bit of graphical representation (diagrams, flow charts, etc.). And there is no chance you'll refactor your code into some monstrosity that both works and conveys all the background information in a meaningful manner.
Sigh... You all say that. It's saddening how all the uncle bob fans are the same, like if you're all made on one single factory.
Nobody is going to read through the entire commit history of a file to simply understand what this one function is doing and why it's doing it this way. You need all the information here and now, right in front of you.
I'm afraid you don't quite understand what kind of experiments you may need to go through before you write down that one piece of code.
Just assume that you don't even have that set up available to you when you're reading the code. What you can have though is a full, nicely written lab journal explaining how things worked out when you tried this, this and that, and why you finally settled on something totally different (and entirely non-obvious unless you read all about the experiments that led to this decision).
No you can't. There is no way an interface can encode all the assumptions (such as, a typical value distribution that led you to your particular hash function choice, for example).
No, unfortunately you cannot. No amount of tests will give you a clear understanding of why you made all those decisions. Not to mention that some tests may require weeks or even years to run.
For example, once I had a latency issue that pops up randomly after few weeks of uptime under a heavy load, and mitigation for it was entirely non-obvious unless you know tons of details of how one specific GPU driver is working, along with some very specific real-time Linux kernel tuning. Good luck encoding all this information in, say, variable names and function prototypes. I'd rather comment that piece of code explaining all the details of an issue, along with relevant plots and their analysis, so that anyone coming back to that piece of code understand what's going on and does not break the mitigation efforts in the future.
I'm afraind you won't recognise reasonable even if it bites you. "Clean code" is as far from anything reasonable as it's humanely possible.
Once again - go and read TeX The Book. This is one book that every bloody programmer must read, every single one. Not some pathetic mumbling of this "uncle bob" unsavory character, but this one. That'd be enough.
Probably you don't even know that TeX is both a source code for a program and a book. Then, again, read it first, and then come back, enlightened.
No, it does not slow you down.
When you crap out your code like crazy, your code is unavoidably a pile of crap. When you put a lot of thought behind your work, and when you write this thought down meticulously, what is left to code is trivial. You're much more efficient this way than if all you do is crapping out some low effort meaningless code in tons.
See, you still fail to get it. You're talking about designing "your code", while my point is that code is not that important, really, without all the background story. Code is trivial, but if you want it to do something meaningful, you must work really hard on a story behind it, not on a code itself.
If you follow the clean code religion - yes, sure. You run around like a headless chicken, with iterations upon iterations of meaningless busywork.
There are much better ways of doing it. Yet you're talking about "efficiency", as if all those iterations of refactoring of yours can be honestly called "efficient".
Code cannot be readable and maintainable if you only see a tiny part of the story, stripped from all the "why?" bits.
Because only the CRUD-level coders are taking this religion so seriously.
It breaks down the moment you try to do something even marginally more complicated.
By CRUD here I mean the level of complexity of requirements, not any specific pattern.
Why not?
Also, why do you need all the information all the time? Don't you agree that humans possess deductive skills and are capable of reading and reasoning?
Because all that information is essential to understanding. All of it. Othewise somebody will come two years later and try to refactor something, breaking things that cannot possibly be covered by tests.
Also, no, you cannot deduce information that was not there in the first place. This is pretty much a definition of what information is. I'll refer you to the algorithmic information theory for more details.
Not to mention that reading the code should require as little thinking as possible.
Why?
How?
Note: the reason why I ask is, if someone tells me, "if you don't do X, the building will be set on fire, oceans will spill out of their shores, the sky will fall, the world will explode", I'd really like to have a convincing explanation of "how?"
That information you keep referring to. How was it obtained in the first place if not for derivation? Derivation from requirements and intention of the design?
Why? I'd rather my colleagues be thoughtful whenever they write / read code.
Easily. Remember my example about twisted mitigation procedure for a rare latency glitch? Without a comprehensive comment anyone would just delete such a code with disgust.
And yes, information is in the requirements, in physical properties of the hardware, etc. - and you distill it through a very expensive and long engineering process before it's ready for consumption.
Want to be "thoughful" instead of consuming a distilled information? Ok. Let me present you with petabytes of raw data from LHC, I'm pretty sure you'll just deduce all of the Standard Model from it.
Whoever deletes code without consideration isn't a very reasonable programmer.
In that case perhaps it makes sense to add a comment. It still doesn't explain why everything has to be commented. Not all code is like that, most code just encodes business rules. No programmer that wants to keep their job would delete the code without thinking about the impact on business rules.
It's funny that you say that. You're the person who says they need all the information all the time when you code.
If someone needs to encode some physics and mathematics theory, there's obviously a need for either comments or another document with derivations, or just a name of the theory, a law, etc. This stuff would be helpful. It doesn't mean that everything has to be commented and only a small portion of the time should be spent on code.
You don't even need code to encode business rules. Write them down as is.
As I said, all this "clean code" religion is only viable for a low effort mindless CRUD-level boilerplate code. Anything marginally more complex, anything that actually worth writing (instead of just automating all the boilerplate), must be commented heavily.
If you find yourself writing all that "business rules" code that does not even need to be commented, you're doing it wrong, it's just a massively inefficient busywork that can be fully automated.
And what should absolutely be documented in tiniest detail, ideally in place, along with the code itself, is where did you get those business rules from.
It's always so funny to find out that nobody have any idea of an origin of some rule that was in the code since forever and was faithfully copied into many systems.
Information, not data. By definition, data is information + noise.
Again, your response didn't address any of my points. For example, where do you get the idea that clean code only applies to CRUD-level complexity? Why do you need all information all the time, as a comment?
You also don't seem to have an understanding of what business rules are, hence seem to think they can be automated. Business rules are basically any feature or an edge case that your product satisfies. In other words, business rules are requirements for the software product. They take form when a programmer implements them as code.
If that was true, programmers would cease to exist. Because any manager would just wave a magic wand, say "I want my product to do X", and it would instantly be implemented.
I think actually the best way is to link Jira with your commits. Jira will describe the requirements and maybe even research, contain links to further documentation, and you can always find a reference to the Jira ticket from every commit you make. You can always find the information with a few clicks, and it's not distracting you every time you look at the code.
From an obvious fact that anything more complex than that is meaningless without tons of background information.
Another example: say, you're implementing some standard. Naming things (modules, functions, classes, whatever) as paragraph numbers of a standard would not make much sense, you'd rather want semantic names, not to mention that one piece of code may address few different paragraphs.
A right thing to do is to refer to those paragraphs in comments. Even better - just copy and paste them, as they're very relevant to your implementation and would save a reader a click and few searches for every little piece of code they're trying to understand. Additionally, it's now versioned with your code. I had a number of unfortunate incidents related to reading a wrong standard edition while looking at a code implementing it.
Now, this standard mentions undefined behaviour quite a bit. You can just implement it in code any way you like, but it's much better to justify your choice of implementation-specific or undefined behaviour, make sure it's consistent for similar cases, etc.
If it's well documented, right where it's actually implemented in code, you're more likely to have consistency and to be able to easily find what this behaviour is in specific cases.
Please read more carefully. Encoding them must be automated, not the rules themselves. Rules are given, and all you can do is understand and document where they came from. But your ways of programming (all that OOPish SOLID "clean code" mumbo-jumbo) is designed to obscure the rules behind tons and tons of boilerplate code, the code that should not even exist in the first place.
In an ideal world, no programmers should waste their time encoding business rules. Luckily, there's a lot of much more exciting things to do instead.
Unfortunately, this world is far from ideal, and a vast majority of programmers and managers prefer busywork to any degree of efficiency. Most of the code written is a worthless pile of crap, and everyone involved seems to be ok with this fact.
No, no, no, please don't do it! It's the worst possible idea, ever. I hate to deal with such code.
Your code is nicely versioned. Jira is not. Just like any other external source - Confluence, whatever else. Then you have to come back to a 5 years old branch to fix an issue for a customer still using this old release, and all you see is a pile of stale links and zero context. Unless you can version your Jira and Confluence along with your code, you should not use them for anything relevant to understanding the code.
I think there are good reasons why Martin considers comments to be a code smell (or "failure"). One of them is that they tend to get out of sync over time and they can state falsehoods about the ever changing code base, which unnecessarily adds to confusion instead of aiding in understanding what's going on.
Comments are often neglected when code changes.
Comments are also often abused by developers by not explaining the intent, but by simply rephrasing or describing what is literally going on, or by labelling sections of more complex multi-line logic, which should be better broken out into smaller methods and modules with self-describing names, making comments ultimately redundant.
I believe the main reason why Bob Martin says that comments are a failure is that they are rarely ever necessary once all other steps have been taken into account and implemented for writing clean code. That's why the chapter about comments also comes a little later in "Clean Code", after the reader already learned a few tricks how to write code that is overall more readable and self-describing.
But Martin also lists in "Clean Code" several examples where comments are justified and needed.
For example when an external dependency, something out of your control, forces you to write a hard to follow workaround. That is a good and valid opportunity to add some explanation in plain English.
Or for clarifying something obscure, expressing the intent, or for adding some useful piece of information. So yes, he seems to agree with you. A comment should express the intent. Not only that. It can also be used to warn of consequences and to amplify a coding decision (e.g. "if we do not trim that string then component XYZ will crash").
The main takeaway from that chapter about comments, IMO, is that comments should not make up for bad code. Code that is in desperate need of refactoring. When code is so complicated and hard to read, when variable names are so nonsensical and control flow structures so nested that comments are needed for explaining what's going on there, then the code itself smells and needs to be rewritten so it can be easier understood. Better, more readable, more self-explaining code will make those comments unnecessary.
I kind of see where you are coming from that Martin's statement may come across as absolutist and condescending. But taken the entire context and the whole chapter into account, I also get what he is trying to say. And I do not read it as something along the lines of "I am better than you by never writing comments, and you are stupid for writing comments". He is also speaking of himself. He is also accusing himself of failing when he runs into a situation where he has to write a comment. We all have to use comments at some point, but running into a situation where we have to write a comment may imply most of the time that something went wrong:
add 1 to x
ordefault constructor
which is obvious to any programmer)set the author, get the author
)// end if (x > 1)
comments to the closing braces --- that code needs to be refactored insteadAnd so on. Still, we cannot always avoid writing comments. But I think Martin tries to strongly encourage us to avoid them and he implies that if the need arises for writing a comment, then something probably went wrong.
The book "Clean Code" is a collaboration between Martin and other authors, so it's not completely born in Martin's vacuum. Several chapters were not written by him. Martin states early on in his book that he discussed and analyzed a lot of existing (mostly Open Source) code examples with his collaborators and the best ways to improve those code snippets they selected for the book. "Clean Code" raises multiple excellent points that stem from decades of experience.
I don't think it's fair to dismiss the entire book and Martin's contributions as a whole based on a single quote you happen to disagree with. There is a lot of really solid advise and insight in it and I highly recommend it to anyone.
That's a failure on the part of the programmer, not of comments. The exact same can be said of variable and function names, but we don't condemn those.
Only if you let them.
Yes, but even my commenting standard condemns that. Just because there is a wrong way to comment doesn't mean there is not a right way.
I could bore you with an entire article series on real-world scenarios where this is not true. The rest of clean code does not preclude actual intent commenting.
I absolutely agree. Comments have their own unique role, and fixing code ain't it.
And again, that's completely dismissing their actual use. I'm advocating for using comments in a capacity that I have never seen even the best code properly fill. And I've seen a lot of code.
I'm sure it does, but even the best material wrapped in unapproachable egotism is still unapproachable egotism. I don't take issues with the content, I take issues with the author.
Oh, I'm not. It's one example. I've read much of Robert Martin's writing, and it nearly always carries his egotism and his inability to distinguish between his opinion and objective reality.
There's a lot of really solid advice and insight in it....and I highly recommend anyone find a less egotistic teacher than Robert Martin to educate them; it is not wise to have to pick out the good advice from the overinflated opinions, when they are portrayed indistinguishably from each other.
Unfortunately, I've run smack into the attitude of "This Always Works, Because Uncle Bob Says" as a coding mentor and manager. It's entirely his own fault, given his predilection to "ALWAYS" and "NEVER" pronouncements, even if he makes a half-hearted attempt at qualifying them.
Just my two cents. I will never be able to respect Robert Martin, not because his ideas are all bad, but because his attitude is contemptible.
Agreed. They can show clearly what they're doing, and possibly what they're trying to do (which is part of the intent story) but not why they're trying to do this. There should be some kind of design documentation around but that will get lost most likely, if the project survives a few decades. Probably not something for JavaDoc comments - you want those to be pretty black-box-ish, to say what inputs and outputs it consumes & produces - but nevertheless important.
There is a funny (as in wierd, not as in haha) passage in the clean coder where uncle Bob describes being given his own office, where he can put a record player in. He then gets 'in the zone' while listening to Pink Floyd. Weeks later he comes back to his code and find his comments are mostly lyrics of The Wall, and then proceeds to criticise the process of being in 'the flow' listening to music while coding and 'commenting code'. Really, he means having discipline and focus, but it really comes across as 'my comments were trippy as balls that day so therefore music while coding and comments in code are objectively bad', which IMHO is a bit of a reach.
So I could agree with some of things you've said, but to play devil's advocate here he probably says this in light of having one function do one thing. And hopefully that function can be easily transcribed. But not every code base has this and not everyone writes descriptive functions, classes, variables. So it doesn't seem feasible.
I agree with your sentiments but doesn't read his statement the same way as you.
I read it more like 'to fail in expressing ourself through code is unavoidable due to neither us nor any language being perfect. When we do fail to find a way to express the what (and the why) through code we use comments to compensate.'
Basically the same way we use comments in law texts to explain the intent behind laws since we are unable to write laws without them. When we need to comment anything it's because we failed to be clear enough.
I think ego is a dangerous thing, and to add to your point, when I started to code I read that same book, after half of it I drop it with almost no interest in programming, why bother, unless yo do it exactly like the book said the code was instantly a piece of crap with no value whatsoever and it existence ofended the gods of the sacred code. Nobody wants to be a worthless shitty coder not worth the air they consume. We make mistakes and we learn we rinse and repeat, that doesn't make anyone unlike godlike Uncle Bob trash, if you write comments not only you are still human you may even be in the right. For a long time I doubted every LOC overthinking every step, not commenting because it is evil and then losing time figuring things out, and yes you will make useless comments because when you are starting you may need more help. I hate code with thousands of one liner functions used just once as much as I hate 500 line functions. Give me "best practices guidelines", keep the "best prectices laws" to yourself, you can't replace common sense with laws.
And personally, I prefer to learn about a craft from someone known by their work on said craft, many books and advices but not a lot of code to show as far as I could find, and that was the first thing I looked for when I learned about this code messiah, I wanted to see how perfect code looked like and I haven't found that working code anywhere.
PD: I don't like TDD either.
By the way have you found some interesting authors on the topic? hopefully not explained with Java, in the university I developed some kind of allergy.
Ironically, the best book I've ever read on the topic wasn't even written for the topic: Dreaming in Code by Scott Rosenberg. That explored the hiccups and weird phenomenon associated with software development so well, it instilled a sense of the importance of many principles coincidentally echoed by 'clean coding'.
But beyond that? Mostly life experience. Lots of good articles on the topic(s) here on DEV...including (I daresay) some of mine.
By the way, I'm allergic to Java too. ;)
Any less egotistical sources you'd recommend?
I don't have any links saved...it's been a while, and I read a lot. However, I can safely say there are hundreds of excellently-written articles on all of Robert Martin's concepts.
Here's what I recommend:
Read multiple sources. Any one perspective can still be a bit off, just by nature of us being human.
Watch the author's tone. Frequent strong absolutes (e.g. "always" and "never"), conflating personal opinion with Objective Law, or a pattern of ignoring or belittling exceptions are all warning signs; if you see these cropping up frequently, use caution when taking their advice. (Admittedly, #2 can be hard to get right every time as an author. Look for patterns, not once-off instances.)
Look at the author's experience. If they've been writing code for only a year, they may not have sufficient experience to personally vet the concepts they're describing. That doesn't mean you ignore everything they have to say, but don't consider it on the same caliber of reliability as an article written by someone who has been coding for 10+ years.
Take time to find rebuttals. For example, if you want to embrace SOLID, try to find some articles (see #1-#3) that discuss possible issues with that practice. No practice or methodology is a magic one-size-fits-all. You can always find valid exceptions, which you should try to be aware of.
And yes, all the above does take a lot of time and mental effort. This is why one doesn't become a senior developer in two years!
I might add, don't neglect your own experience as you put the things you learn into practice. If you keep using (say) TDD or Intent-Commenting (that one's mine), and it is actually inhibiting your work instead of aiding it (no matter how many different "flavors" of the practice you try), amend or drop it. Ultimately, you have to learn what helps you produce the best result.
I recently finished reading this book with some colleagues at work. The consensus opinion to come out of it is that you won't fully benefit unless you read the book critically. While 80% of the book is good advice, about 20% is controversial to downright bad advice. Plus, most of the book is grounded in quite outdated Java versions, some of it in dire need of an update (and largely irrelevant if you don't use Java).
If you're new to the idea of writing "clean code", you might not be able to recognize the 20% of bad advice. So if you do read this book, remember to take everything with a grain of salt; it's just one more perspective to keep in mind while writing code, not the definitive perspective.
This is exactly the point I was making earlier!
Robert Martin has a lot of good ideas, but his apparent ego prevents him from distinguishing between his opinion and provable reality.
I recommend developers learn clean coding from more trustworthy (less egotistical) authors, who have vetted these ideas in their own careers. I can never recommend a young developer read Robert Martin's work directly.
I am not a big fan of commenting code, but sometimes it is required (but not always). Developers hardly read comments and most of the time it's just create noise.
Jason, I appreciate your
defensive approach to support code comments, but it's sounds to me an unnecessary conversation. It's all depends on agreement between team members whether to add comments and how much.
Can you please show some respect for Uncle Bob, based on his contributions,
To be honest, I don't think Jason was disrespectful in any way. He said Uncle Bob has a lot of great ideas. And pointing out that Uncle Bob has a gigantic ego which prevents him from distinguishing between his opinion and provable reality, is just the truth. He is still man with a lot of good ideas.
Amem to that. There are a lot of good ideas in his books. That's a fact. But distinguishing between the good and the bad advice is difficult when you are just starting to learn how to code.
A video by Bob Martin delivered in Norfolk UK blew my mind. It starts off very strangely talking about human biological evolution. That seems very odd but stick with it. He then drops the bomb on what makes clean software architecture which is that everything must be a plugin to your business logic to keep it clean youtu.be/o_TH-Y78tt4
Oh god, this kills me, I'm from Norfolk! Such a brilliant speaker.
Wow, you beat me to it! I'm currently reading this book again and was planning on sharing the same sentiments on here soon 😂
Totally true though, this book is an invaluable resource. Highly recommend that anyone trying to get serious about porgramming takes the time to read it.
I love this quote!
Me too! I can't take credit for this one though, I did google around to see who originally said it, but failed miserably!
haha it's still a great quote!!! It might be John Woods.
While this may be completely true, it is completely forgetting the archenemy of every programmer, "The Deadline". When you are fighting the clock, and you have a choice, "Make it pretty, or make it work." This is typically when style goes out the window.
Yeah, unfortunately, this happens far too often. Especially when the product is new and the business wants to see results fast. It's in the developers' hands though, if they think it's going to take longer to make the code clean, maintainable, extendable then it's their responsibility to let the appropriate people know!
TL;DR: read the book, take it with a grain of salt, and try to take some of what Bob said into your daily thoughts about how some things are done.
As much as a like this book and it's commentary, this requires every developer that's ever touched a keyboard to live, eat, and breathe this ideology for it to be consistent. That doesn't mean that some of his suggestions can't be used, it's just that if you wanted this to be the holy Grail, it would really need to be executed perfectly.
That being said, look at CPPCoreGuidlines. Good standards based around a community and Bjarne. There are others like it for other languages.
Thank you for wrapping this up. I absolutely agree that every developer should read this book. The book gives really good advice on how to code and also what to express with code. In my personal opinion, Uncle Bob sometimes is a bit extremistic in making an argument though. He tends to explain a single aspect so sharply pointed, that it can be in the neighbourhood of "wrong" or contradicts his own arguments from other chapters. So when reading the book, each thing should be seen as a proposition how to work. Trying to understand what the author wants to express and how he came there is key to understanding the argument and bringing it to life under the own circumstances.
What I don't like is to see this book as the "Holy Bible of code", which indicates that every single letter has to be obeyed to. Not understanding the rationale but still adhering to the words as they were written can cause all different kinds of new classes of problem.
Nope. It is full of ill, destructive advice and OOP zealotry. Programmers who took this broken book too seriously are lost, and I personally will never want to have to work with any of them.
Before this book one should read the Pragmatic Programmer book, that is referenced several times in the Clean Code book, that now have a new edition to commemorate the 20th Anniversary from the first release.
Some comments have been hidden by the post's author - find out more