DEV Community

Discussion on: The ONE book every developer MUST read!

Collapse
 
combinatorylogic profile image
combinatorylogic

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".

Thread Thread
 
guitarino profile image
Kirill Shestakov

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.

Thread Thread
 
combinatorylogic profile image
combinatorylogic

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.

Thread Thread
 
guitarino profile image
Kirill Shestakov

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.

Thread Thread
 
combinatorylogic profile image
combinatorylogic

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.

Thread Thread
 
guitarino profile image
Kirill Shestakov

Thanks for a good chuckle. Read your own comment with fresh eyes and tell me, who sounds more like a zealot?

the theory you had to derive before you'll even start thinking of architecture

Before you start designing architecture, there's a requirements gathering stage, which is done via Jira or something like it

really matter is how you got there - all the background work that ended up in this code

You have version control for that

all the experiments you had to conduct and record

You can write tests and your "experiments" are forever recorded and actually validate your code

assumptions you're making about the data

You can use interfaces for that

about performance requirements

You can write performance tests as well

Take a look at any of the good examples - e.g., TeX and Metafont.

Interesting. Well then, I'll leave you to writing TeX for your programming. I'll keep using reasonable methods.

Code should be the least of your concerns, and writing code should take a tiny proportion of your time.

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.

if all you do is some CRUD that nobody cared to automate yet

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.

Thread Thread
 
combinatorylogic profile image
combinatorylogic

Before you start designing architecture, there's a requirements gathering stage, which is done via Jira or something like it

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.

You have version control for that

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.

You can write tests and your "experiments" are forever recorded and actually validate your code

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).

You can use interfaces for that

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).

You can write performance tests as well

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.

Interesting. Well then, I'll leave you to writing TeX for your programming. I'll keep using reasonable methods.

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.

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.

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.

Okay, I know what you mean, you should always design your code before you write it, and it's fair.

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.

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,

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".

And, the only requirement, to my mind, is that the final result is readable and maintainable, then the software product can survive and thrive.

Code cannot be readable and maintainable if you only see a tiny part of the story, stripped from all the "why?" bits.

Where do you get the idea that CRUD has to do with it?

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.

Thread Thread
 
guitarino profile image
Kirill Shestakov • Edited

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.

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?

Thread Thread
 
combinatorylogic profile image
combinatorylogic

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.

Thread Thread
 
guitarino profile image
Kirill Shestakov • Edited

Because all that information is essential to understanding. All of it

Why?

Othewise somebody will come two years later and try to refactor something, breaking things that cannot possibly be covered by tests.

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?"

cannot deduce information that was not there in the first place

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?

Not to mention that reading the code should require as little thinking as possible

Why? I'd rather my colleagues be thoughtful whenever they write / read code.

Thread Thread
 
combinatorylogic profile image
combinatorylogic

How?

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.

Thread Thread
 
guitarino profile image
Kirill Shestakov • Edited

anyone would just delete such a code with disgust

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.

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.

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.

Thread Thread
 
combinatorylogic profile image
combinatorylogic

Not all code is like that, most code just encodes business rules.

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.

You're the person who says they need all the information all the time when you code.

Information, not data. By definition, data is information + noise.

Thread Thread
 
guitarino profile image
Kirill Shestakov

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.

massively inefficient busywork that can be fully automated

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.

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.

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.

Thread Thread
 
combinatorylogic profile image
combinatorylogic

For example, where do you get the idea that clean code only applies to CRUD-level complexity?

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.

You also don't seem to have an understanding of what business rules are, hence seem to think they can be automated.

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.

If that was true, programmers would cease to exist.

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.

I think actually the best way is to link Jira with your commits.

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.

Some comments have been hidden by the post's author - find out more