It's probably useful to un-read Clean Code, though I don't really have a recommendation for a good replacement. The replacement is something like "Make a lot of mistakes and develop good taste based on your experience."
One of the problems I have with it is the advice comes down to unhelpful abstractions that tries to wave away mechanical empathy.
I spent years writing Ruby and found clean code OK, but preferred Sandi Metz’s writing. Then I started doing some Go and Bill Kennedy made me think about mechanical empathy more. Recently I’ve been diving back into my old haunt of C, particularly more modern C idioms and the C23 standard as I need very fine grained control for latency and memory efficiency reasons for the apps I’m writing (in a very different space to where I worked in Ruby). It’s kind of blown away a lot of the advice from clean code for me.
The thing you’re programming has a CPU with registers. There’s a stack. There’s a heap. The choices you make choose how those things are used by the language implementation you’re using. Languages and methods that try to pretend none of that is happening can lead to very inefficient code that makes everyone sad.
Yes, your code needs to be readable. It has to be maintainable, but the clean code way of doing things doesn’t seem to do that very well AND introduces patterns that can make it hard for compilers and interpreters to optimise.
But it captures it perfectly, a large number of engineers go from jr to intermediate with their new found tricks. Except they cling to these tricks like it’s law, they have upskilled in one direction while sacrificing the open minded pragmatism for dogmatism. They’ll argue with you about these things, it’s in a book how can you not adhere to it!!?
If you can onboard these lessons and still recognise the spots where it’s begging for some best practice but you should break the rule this time, then congrats you’re ahead of the curve, it takes most engineers a frustratingly long time to get pragmatic. If I had a penny for every awful DRY abstraction that became impossible to reason about, I’d have retired.
"Clean code", when not applied judiciously, tends to result in overly complex code with a lot of repetition. This may be desirable when very strict decoupling is needed in complex projects, but in many projects it makes things worse rather than better.
I suspect that one of the main reasons is that people read it and think they have to adopt all of it.
Personally I still recommend it to people but with the caveat that they need to think about what aspects from it they adopt and which don't make sense for them in their environment. E.g. if function calls are expensive in the language they use and its compiler doesn't optimize their code by inline the ones it can, then they probably don't want to break things down to the level that Clean Code recommends.
I also love Clean Code and think it unfairly gets a bad rap, but here's a great, sometimes hostile, conversation with the author that touches on the issues:
Just for context, this was posted to Github by the author of Clean Code himself, Robert C. Martin, while exchanging messages with Casey Muratory [0]. They talk about performance, about testing, and maybe other stuff (I'm at less than half of it)
I think that some of the advice hasn't aged well into modern language features and computer power, similar to the GoF Design Patterns book. Rather than an entry level book, this would be better for a budding intermediate who can parse what is good and bad about it.
But, even then, other resources are better IMO. (Metz, Ousterhout, Kay, PragProg, language-specific design patterns books, etc.)
The experience of doing things wrong is valuable, but I think you also don't want to get quagmired there. It just depends on how voraciously/quickly you read and seek out better patterns.
(Also, elephant in the room, Uncle Bob has been very vocal and opinionated on the internet about various things and it hasn't endeared many to him because of it)
I think it depends. For me, I can see how it helps a brand new developer get a feel for code style.
That being said, some of the advice in the book is simply dated, some of it seems to break code down arbitrarily instead of on responsibility.
On top of this, you get people who pedantically follow it and don't let a team of experienced engineers develop a style that works for them it's really annoying and it can make the codebase a bitch to work on.
In the end, it should be a guide. And you should be thinking about what bits to take. But what ends up happening is "uncle Bob says...".
If you're interested in performance, you can read https://algorithmica.org/ and https://people.freebsd.org/~lstewart/articles/cpumemory.pdf