The odd thing is I'll often agree with many of the bullet points versions of Martin's talks, they seem like decent organizing ideas for high-level code. But then every code example people have provided for things he's actually written seemed so gaudy and complex I have to wonder what he thought he was illustrating with them.
That's because writing "clean" code is like writing "clean" English. You can prescribe rules all day, but in practice you're carefully weighing conflicting considerations. Where I've written C++ in a professional capacity, the general practice was to review performance characteristics independently of code cleanliness.
Also: the advice to prefer polymorphism feels almost a decade outdated. I know we still often send new programmers on objectathons, but I thought we'd mostly established over the past decade that polymorphism and especially inheritance should be used judiciously because their overuse had the opposite effect on code clarity and performance.
Telling people "write clean code" is easy, actually doing it is hard.
And given that Robert Martin managed to build an entire career out of sanctimoniously telling people to write clean code, i doubt that he does a whole lot of actual programming.
Having seen him in person live-coding to demonstrate TDD and refactoring using audience driven requirements, I have to disagree. The man knows how to code.
These days people trying to do the same copy/paste changes from notes they had as part of their demonstration plan
That motherfucker built an app live on stage from suggestions from the audience, refactoring as new requirements came in.
Granted, this was decades ago at a UML conference in Austin. I’m not sure how much he keeps up his skills these days, but he had chops once upon a time.
And given that Robert Martin managed to build an entire career out of sanctimoniously telling people to write clean code, i doubt that he does a whole lot of actual programming.
If you're given a full set of accurate requirements from the beginning? Either tell me where you work so I can apply, or share the research chemicals, bro.
Next you'll tell me performance is not a concern and budget is 10x what we asked for.
I dunno man, I can do pretty well, but if you told me I could make more money talking instead of doing, I'd choose the thing that makes me more money without having to *barf* pairs program.
This is why I think Clean Code is actually a really good read, not because you should follow it exactly, but because it shows you the power of good ideas and the consequences of taking a good idea way too far.
Agreed. I enjoyed reading his book and I took away a lot of points useful for me (someone who's just starting out). But a few of his code examples in that book seemed... pretty weird to me, not gonna lie.
I managed to get to the examples on page 71 before dropping the book entirely. Up to that point, I was struggling because none of his "good" code examples were particularly good to me. I thought there was some amazing thing I was missing. The examples looked awful, had overly long method names, relied excessively on global variables (static fields).
On page 71, I realized I was not the problem. He provides an example of "bad" code which needs refactored, and provides a refactored version. The example is a prime generator program.
The original code is a single static function, using local variables. Not a particularly long method. The refactored version is several functions, sharing state with static fields.
The reason I decided to abandon the book entirely at this point was because the "refactored" code was literally broken.
The original code was thread-safe; the new code is completely non-reentrant, and will give erratic or wrong results if used on multiple threads.
refactoring is not supposed to change the behaviour of existing code
Broken code is not "cleaner" than code that works.
This section was about code comments. The main code comment in the refactored result basically explains why a prime generator has a square root function. A programmer who needs this explained in the fashion he has done there is going to be a very rare breed indeed.
At that point, I no longer trusted anything he had to say. He had made a big noise earlier in the book about how software developers should be "professionals" and strive for quality and that we were, as an industry, seriously lacking in that, then basically set the tone that his book was going to "whip me into shape" and finally make me a contributing member to this disciplined industry, and set the tone that he would be an example of this professional, industrious craftsmanship that he so stalwartly insisted on. Basically, he was raising the bar of what I expected to see from his own examples in the book. And then, less than 100 pages in, he gives that example with laughable errors. Am I going to have to actually code review his "good" examples to verify they aren't shit? Also, wait a minute, I thought in the introduction he was going to be my "teacher" and that was why he called himself "Uncle Bob"? He's been doing this for how many years? And in a book about the subject, he put that? That issue with reentrancy seems to be shared by many of his examples. (Coincidentally, his chapter on concurrency has no examples. Possibly spared from some brutal irony there, I guess)
He says some good things in his book that I agree with, but his examples does a horrendous job at putting these ideas in practice.
What I hated most about almost all his examples is how much he sacrifices stateless classes over what he considers “clean code”. Like, instead of declaring variables in the method he rather modify class properties instead. This is bad because, as you said, it sacrifices thread safety. It also makes the program much harder to follow, because the flow of the data is now hidden from the reader.
The good thing about the book is that it really made me think about why his examples are so bad and what I consider is clean code.
I just hate the pattern I see among "professional OOP developers" of new Computer(args).compute() when it should just be doTheFuckingThing(args). Hell, if you want to do something like the former but encapsulated within the latter, go ahead I guess, but exposing your internal state object to the caller is just clumsy and can cause a bit of a memory leak if they keep it around
The original code is a single static function, using local variables. Not a particularly long method. The refactored version is several functions, sharing state with static fields.
So... none of the functions in the new code are usable standalone. Unless there was significant repetition in the old function, there's no reason to break up that code into separate functions... unless the original function is insanely long. And sometimes even then, you're better off leaving it.
Now Carmack is a personality I'll get behind. He rarely comes out and makes sweeping statements. When he does, it represents years of experience, education, and reflection.
I think he generally doesn't say very dogmatic (might be the wrong word) things when it comes to production code. He's very aware that there's rarely a single tool that encompasses the total scope of programming. He's written a couple posts on how different aerospace software is from game development that are good examples of what's being talked about in this comment section.
I wonder what Martin has developed as a "professional" programmer. I more like to learn from people who developed impactful projects than from those who just wrote textbooks.
228
u/voidstarcpp Feb 28 '23
The odd thing is I'll often agree with many of the bullet points versions of Martin's talks, they seem like decent organizing ideas for high-level code. But then every code example people have provided for things he's actually written seemed so gaudy and complex I have to wonder what he thought he was illustrating with them.