Unlikely, unless his view has changed substantially in the last seven years: https://blog.cleancoder.com/uncle-bob/2017/01/11/TheDarkPath.html
I think his views on how to achieve good quality software are nearly antithetical to the goals of Rust. As expressed in that blog post and in Clean Code, he thinks better discipline, particularly through writing lots and lots of explicit unit tests, is the only path to reliable software. Rust, on the other hand, is very much designed to make the compiler and other tooling bear as much of the burden of correctness as possible.
(To be clear, I realize you’re kidding. But I do think it’s important to know just how at odds the TDD philosophy is from the “safe languages” philosophy.)
This is an absolute terrible post :/ I cannot believe he thinks that is a good argument at all. It basically boils down to:
Here is a new feature modern languages are starting to adopt.
You might thing that is a good thing. Lists various reasonable reasons it might be a good thing.
The question is: Whose job is it to manage that risk? Is it the language’s job? Or is it the programmer’s job?
And then moves on to the next thing in the same pattern. He lists loads of reasonable reasons you might want the feature gives no reasons you would not want it and but says everything in a way to lead you into thinking you are wrong to think you want these new features while his only true arguments are why you do want them…
It makes no sense.
Yeesh, I thought you were being hyperbolic, but it really is that bad! He even has this massive self report towards the end:
And how do you avoid being punished? There are two ways. One that works; and one that doesn’t. The one that doesn’t work is to design everything up front before coding. The one that does avoid the punishment is to override all the safeties.
And so you will declare all your classes and all your functions open. You will never use exceptions. And you will get used to using lots and lots of ! characters to override the null checks and allow NPEs to rampage through your systems.
Uncle Bob must be the kind of guy who makes all of his types any
when writing Typescript.
For example, in Swift, if you declare a function to throw an exception, then by God every call to that function, all the way up the stack, must be adorned with a do-try block, or a try!, or a try?
I agree with him on this point. Sounds similar to how it’s in Java, and I hate it. I always wrap my exceptions in a RuntimeExceptions because of this.
I disagree with him the rest of the post. The job of the programmer is to communicate the intent of the program. Both for others and for yourself. The language provides the tools to do so. If a value is intended to be nullable, then I would like to communicate this intent. I think it’s good when a language provides this tool.
Tests don’t communicate the intent of the code. Tests can’t perfectly validate all the possible edge cases of the system either.
Checked exceptions are powerful but misunderstood. Exception types are a useful part of the facade to a module - they express to a caller how it can go wrong even if used correctly.
Runtime exceptions are typically there to express contract-breaking by callers; although as an alternative return mechanism I’ve seen them used to simplify the inner workings of some frameworks.
I think they get a bad rep because there aren’t a ton of good examples of how to use them - even the java classpath had some egregious misuse initially that helped turn people off the key ideas.
Imo, if a method require the caller to do error handling, then that should be part of the return value. For example, use optional or either. Exceptions shouldn’t be part of any expected control flow (like file not found). Exceptions is an emergency panic button.
His take strangely acknowledges that defects are caused by programmers, yet doesn’t want to improve the tools we use to help us not make these mistakes. In summary, git gud.
Experience has taught me that I’m awfully good at finding and firing foot guns, and when I use a language that has fewer foot guns along with good linting, I write reliable code because I tend to focus on what I want the code to do, not how to get there.
Declarative functional programming suits me down to the ground. OOP has been friendly to me, mostly, but it also has been the hardest to understand when I come back to it. Experience has given me an almost irrational aversion to side effects, and my simple mind considers class members as side effects
To my knowledge, the Rust’s book actually encourages writing as many automated tests as you can, as the compiler can’t catch every type of bug in existance.
rather strongly typed Java.
[In Java] you can also violate many of the type rules whenever you want or need to
Okay. Well maybe being able to not spell out types every single time would also count as not burdening the programmer ¯\_(ツ)_/¯
I bought Clean Code when I started learning programming, some of it was useful, but now I understand that it was too opinionated for a beginner
Edit: also
Whose job is it to manage that risk? Is it the language’s job? Or is it the programmer’s job[?]
It is language’s job to enforce risk management wherever possible, humans are demonstrated time and time again to be poor at risk management (same for the other questions like ‘whose job it is to check for null
s’
Edit2:
Defects are the fault of programmers. It is programmers who create defects
… and that is why he proposes to not help programmers with language means. I never thought that views of how problems should be tackled might differ so much while having in mind the same reasons and goals.
Albeit I do agree that one must write tests, even if language helps, not everything can reasonably be automatically checked