Hacker News new | past | comments | ask | show | jobs | submit login
Beyond Clean Code (tobeva.com)
78 points by pbw 20 hours ago | hide | past | favorite | 59 comments





Casey Muratori is basically describing Data Oriented Programming. Perhaps the most famous talk about it was from CPPCON 2014 [1]. I come from an embedded background (microcontrollers and bare metal) so I'm pretty sympathetic to his argument. If you work in it long enough, it feels natural and "clean". Uncle bob's Clean Code probably feels natural to Java devs.

Personally, my biggest gripe comes from experiencing people trying to introduce it to a team. Inevitably someone tries to enthusiastically implement some part of it and suddenly are writing 1 line functions everywhere. I think this is the type of thing Casey is also implicitly talking about when he's railing against the rules being brought up.

[1] https://www.youtube.com/watch?v=rX0ItVEVjHc


I think DOD is great and Casey’s optimized version is great. But his claim that OOP inevitably leads to horrible performance is factually wrong. And he’s repeats it over and over even after the viral video. My main goal with the article/video was to debunk this false claim of his.

Also, something most people overlook is the OOP example in his article is 100% vanilla OOP. There is nothing “clean code” about it. So he’s really railing against OOP and not clean code.

My article shows that the impact of the overhead of OOP, but really the impact of the overhead of _anything_, can range from huge to basically zero, depending on the time scales involved. So my main point is you should be very mindful of the time scales involved.

But if you want to rule out OOP for non-performance reasons I think that’s fine. All styles have pros and cons, and situations can vary widely. Like for instance the existing style of the project and the skills and preferences of the people involved.


My work has adopted DOD for roughly the last 3 years. Compared to OOP/FP[0], I would say DOD is generally more performant, more work to set up initially, harder to adapt to small changes, and easier to adapt to big changes.

DOD is generally going to have less in the way of user-defined classes/types. This can sometimes make it harder to convey the intent of the code, but in term it means there's a lot less to do if there's a big change in the problem domain – e.g. you don't have to refactor a whole class hierarchy.

Jonathan Blow has mentioned some ideas in his language Jai that would let you write code that can easily switch between OOP and DOD ideas, e.g. Array of Structs vs. Struct of Arrays, and I've seen that in some languages like Julia as well. I'm hoping it becomes more common place so that there's less of a tradeoff to make.


I’m not at all familiar with Julia but that sounds interesting. I’ve been thinking recently that with AI we might eventually decouple the style of the source code from the style of the executable code.

That is, let you toggle from DOD to OOP in your IDE. The way you can vary the font in your IDE today. Very non-trivial but in the long term could happen.


In addition to Mike Acton's talk, there is also the "DOD Book": https://www.dataorienteddesign.com/dodbook/

Don't see a problem with one line functions per se, especially if the name of the function helps understanding the code

There no problem with them, and they can often be useful. But there is a problem if all the code is only functions of one or two lines, or when people move things to functions when it just doesn't make much sense, "because it's Best Practice™".

Pylint warns if you have “more than X” for a lot things like local variables, number of arguments, number of member variables, etc.

For most of these the limits are in the 5 - 9 range but for lines in a function/method the limit is 50 lines.

I agree with this. One line functions are okay sometimes but 50 line functions can be fine as well if clear and well written.

A lot depends on the cyclomatic complexity: how many loops and branches, how drastically the indentation varies basically.

So I disagree with how strenuously Uncle Bob harps on short methods, although paradoxically I do agree many methods in the wild are too long. Most of them grew to be too long because it’s easier to add a few lines to an existing method than to refactor things —- particularly if a code review is required.


Nah, short and single-line functions can be good.

Something I'm happy about is if I can create an object to implement some isolated part of the domain in a way that's obviously correct and consistent within itself. For example, currently I'm working on a bit of a backup analyzer to identify different problems, estimate sizes and such. One object in there is the PGBackrestState and it has a whole bunch of one-line methods like total_size_on_disk, full_backup_count, average_incemental_size. Most of these are just one list comprehension. That's nice, readable, correct and stable code - and it makes other code more readable.

But some functions in that code base are an implementation of pretty much a flow chart of grabbing information, figuring out the state of the system and eventually dropping into more specific analyzers. This can be a whole bunch of imperative code in a function. And I've tried, but chopping this into smaller functions makes the overall idea and control flow much harder to understand. Sometimes a rough screen length of logic can be easier to understand as well.


> Uncle bob's Clean Code probably feels natural to Java devs.

No.


I like this article. At the start I feared it was going to be one of those polemics written by someone who's never had to read other people's code, or worry about speed, efficiency or third party users.

However thats not the case. The author has distilled lots of experience into something reasonably readable.


The other cool thing about an OOP approach to this problem is that you can hide your optimized LUT behind the OOP if you're careful about the design of it. This lets you have your cake and eat it too. Your users who might be more comfortable with an OOP approach get a way to declare the kinds of shapes they're interested in and the number of shapes they want to work with. Then you can take responsibility for building a LUT that meets their needs and give them the supporting optimizations they need to be successful.

If anyone wants to read the antithesis of Clean Code, check out "A philosophy of software design"

Amazing book. My favourite parts are the framing of fighting complexity as the main goal of design (strategic vs tactical thinking) and the idea of "deep modules".

I simply love this book!

the problem with code is that the abstraction changes and data needs to be migrated:

e.g. a user is enabled if they have paid... time passes... now a user is enabled if the team they belong to has paid. now you need to move the logic to another struct / class and the data to another table.

now this is where "payables" and things come in and you start going the path of clean code with 1000 classes.

instead, the best way to do this is immutable data streams and event listeners.

after over a decade of programming, i feel for most software with a customer focus (not low level, embedded etc), immutable data streams where data flows through and listeners do things to themselves is the best way.


I fully agree, but this requires a certain level of experience to organize code in a way that makes it easy to navigate and modify. It's quite easy to end up with with "rube goldberg" code where you don't know what listeners are being triggered by what streams. Or to end up with a ton of edge cases where things aren't handled properly when issues occur.

Yea agree. I feel one of the best books ive read that makes this concrete is Grokking Simplicity by Eric Normand. It’s less about functional programming and more about functional thinking. Lots of concrete great advice in that book.

Same conclusion here. May I ask about your stack/domain?

The most important thing when evaluating things you need to know is: context matters

Principles arent universal across technologies

Hell, principles arent even universal across software kind (e.g goto arent used in C# web dev, but std lib? yes)


And across teams, business.

The context in this case being that Robert "Uncle Bob" Martin is a charlatan and an impostor.

this comment says more about you than him :)

So like, Clean Code really does say you should write four line functions, and does not put caveats on that statement, Uncle Bob even gives a lengthy terrible-looking example of a class written with 4-line functions and holds it up as the ideal. His views as expressed in that book are extreme and uncompromising, the “everything in moderation, there are many ways to write clean code” stuff is a rhetorical act he does when people call him out. Then when they’re gone and he thinks he can get away with it he starts speaking in absolute statements again.

Like, this is a conversation Uncle Bob had with Casey Muratori on GitHub, I came away feeling like Uncle Bob is more interested in playing rhetorical judo than anything else: https://github.com/unclebob/cmuratori-discussion/blob/main/c...


As the OP, I was not arguing that Uncle Bob's advice is good; I was arguing that performance is not the reason to reject his advice... unless you are counting nanoseconds, in which case performance is a great reason to reject his advice.

It's a story of two worlds. Casey lives in a world where nanoseconds almost always count. He says OOP is horrible for performance, but he really means it's horrible for performance in that world. But Uncle Bob's book is about a different world: business Java programming from 10+ years ago. There, the overhead of OOP is almost always negligible. One of my main points in the article was just to be aware of the world you are in.

Performance aside, is Uncle Bob's advice good or bad? I think it's a mixed bag. His four main books total 1,552 pages. Some of his advice is rooted in the Java programming world from the 1990s and 2000s, but I think other advice (like "use good names") is valid today in many languages. Sorting through all those pages of advice would require a much longer article; I didn't try to do that; I just tried to address Casey's performance claim, since I think he's totally wrong (in many cases) even while being totally right in other cases.


I’ll add that “use good names” is good advice. But “use the names Robert Martin prefers” may or may not be good advice.

But performance isn’t the reason to reject his advice: common sense and good taste are more than enough of a reason.

When he wrote Clean Code, Uncle Bob created a monster. Tons of people hold that book up as the Gospel of how to write not just OOP Java code, but all code.

Now is Uncle Bob really to blame for what other people do with the ideas in his book? Absolutely yes. All throughout he writes in a super authoritative tone, snarks at people who disagree with him, and asserts that his 40 years of software engineering experience mean his opinions must be right and that he doesn’t have to explain why.

The reaction to his writing is a product of the way he wrote it, and the reaction sucks. In workplace after workplace I’ve had to push back against people trying to sully nice readable code by blindly and stubbornly applying his principles.

It’s an endless struggle, one that would be helped if, like Merlin Mann (creator of Inbox Zero) he looked at what was happening and disavowed his creation and spent years working to correct the public’s misconceptions. But Uncle Bob doesn’t want to do that, so here we are.


> But performance isn’t the reason to reject his advice: common sense and good taste are more than enough of a reason.

My article and video are responses to Casey's mega-popular video "Clean Code Leads To Horrible Performance," which has 873k views. In it, he falsely claims that clean code always leads to horrible performance when, in fact, it only sometimes does. In my article/video, I explain when OOP/clean code does and doesn't lead to horrible performance.

My goal was to debunk Casey's claim since he was factually wrong and continues to mislead people about this to this day. I partially agree with your point that Uncle Bob's advice is wrong for other reasons. His main four books total 1,500 pages. Some of the advice is good, some is dated, opinionated, or just wrong. Untangling all that would require a much longer and very different article, which wasn't the one I was writing.


In fact, if Uncle Bob really doesn't want 4-line functions, and wants moderation, he should write a better book. Whatever he claims to mean, everyone sure seems to think that's what his book says.

I personally found it to be one of the most needlessly dogmatic things I've read.


For me, I bought "Clean Code" because it was, at the time at least, quite highly recommended. After being rather confused for a while, I finally stopped reading right around page 141 when I realized that the reason his examples looked awful were because they were.

In that section of the book, he takes a Java port of Donald Knuth's PrintPrimes program, and refactors it. But in doing so, he actually breaks it. He moves state out of local variables and parameters and makes them all static fields, and then refactors the code into long-winded methods that specifically perform side effects or operate on those fields (names like isNotMultipleOfAnyPreviousFactor(), isLeastRelevantMultipleOfNextLargerPrimeFactor()). But the simple act of moving state that would otherwise be part of the stack frame into static fields means he has changed the behaviour of the code - it is no longer thread safe! calling it from different threads will have undefined results because all threads will be operating on the static fields. He demonstrably made the code worse!.

It invalidated the entire book for me at that point. Here's "Uncle Bob" trying to pretend to be some aged, skilled, craftsman hand guiding us young, ignorant whippersnappers into being proper craftsman and not only can't he properly refactor a simple prime number sieve as a demonstration, but he's so blind to awful code that he doesn't even see it in his awful example enough that it gets published in the same book that complained about programmers who don't have "code-sense". Mistakes and "errata" are one thing, but when he makes such a big noise about "do it right the first time" and then has an example where he refactors and literally breaks something, that's another.


I started reading the code Martin wrote with his son for the “FitNesse” acceptance tracking framework.

The code was simply God awful. Nearly every method was tagged ad “throws Exception”, no comments, and the famous endless sea of classes with only a few lines of code per method.

The code itself ran with constant exceptions filling up the logs. This was going back over a decade or more when I looked at it.

You can see his lineage of trying to sell consulting services and books all the way back to the comp.object Usenet groups back in the 90s.

Sadly he still commands big fees to speak at various conferences and companies, I was very disappointed when he spoke at Bloomberg many years ago when I worked there.


Interestingly enough, John Ousterhout was a recently on Book Overflow podcast and he says he uses this very refactoring but on reverse to teach good software design. So it’s good for something!

In my opinion the only good part of that book is the title.

I even hate that the title got popularized. Code isn’t “clean” or “dirty”. It works or it doesn’t work. That’s the most important aspect. Another very important aspect is that It’s readable or unreadable. Readable code may be very long winded, but I would much rather have that than somebody’s idea of a “clean” concise very abstract piece of logic.

I hate when I get comments on a PR talking about some subjective piece of code suggesting an alternative that they think is “cleaner”. How clean a piece of code is shouldn’t be a part of consideration while reviewing any code. Instead, like I said before, the only thing that really matters is if it works and if it’s readable. I wonder how many junior engineers have been bogged down with pointless PR comments over the years because of this idea that code can somehow be “neat” or “clean”.


I always took it more as readable code.

I mean. It’s not like people pushing “side effects” (read: literally any change at all) aren’t also being overtly dogmatic, and writing utterly terrible code.

Uncle bobs book didn’t age well, but neither will the dogmatic stances on immutability and side effects.


Avoiding side effects as much as possible is not a new idea, though; it's been around since at least the 80s. You can just ask people who have worked on Haskell code written in the past 25 years to determine for yourself if the idea aged well or poorly. Opinions will probably be mixed, though, not clearly one way or the other.

In this case, By "side effects" I mean non-obvious changes to the static state, Where a seemingly simple function will both rely on static fields to evaluate it's result as well as make changes to various other fields that will subsequently change the result of that function going forward. I don't think one needs a dogmatic adherence to immutability and avoiding side effects to find that to be undesirable.

Has uncle Bob actually produced any useful software? Are there any examples of his work out there which can be analysed?

He’s got a GitHub. This seems to be the most notable thing: https://github.com/unclebob/fitnessedotorg

Yeah, I get the impression that he just sells his image as some "guru" of software engineering, and that he doesn't actually deal with or write much real life code.

I think the aspirations of the agile manifesto are great, but basically everyone involved in it was an enterprise software methodology consultant. I forget who the exception was; someone will remind me.

People can give good insight about things despite even not creating these things, see e.g. physicists who study atoms

It’s more like someone who gives talks about smashing atoms to study subatomic particles without ever having been to a particle accelerator facility.

You can’t replace experience. There’s theory, then there’s practice. Ideas are worthless until tested in reality.


Oh I think there are plenty experiences out there practicing various strategies of clean code in the wild which he can observe without creating them himself

Isn’t that the same case for Robert Martin? I’m not going to be the one defending Uncle Bob, but most of the people out there giving advice about “clean code/architecture” come from the consulting world without any work that can be analysed.

Those are the same person

I always confuse them. I meant Martin Fowler.

I am rather ignorant of the world of consulting. If someone like Uncle Bob consults a company and the company implement his ideas with his guidance, then is a consultant like Uncle Bob typical gone by the time maintenance rolls around?

I ask because I can see his ideas being great to him if he is never around for damage control because what feedback does he truly have that cannot be fought back with some 'Get out jail free' card like "The company deviated from my plan after I left!"


Either that or the company hires yet another consultant to rewrite everything because it can't be maintained.

Uncle Bob sounds good verbally.

Like "small functions." I say, okay, okay, stop writing these 2000 lines of spaghetti, I'm a hundred percent on board.

Then when you get to the concrete example, it's decomposing this 15 line function.

Good idea. Calibration is waaaay off.


Perhaps the Uncle Bob principles do not create the best code, or most clear code, but more dogmatic adherence does make it harder to create the code I see on a daily basis that is so much worse and much more unmaintainable.

I suppose if the options are "Uncle Bob's Rules" and the straw man of "No Rules" that could be true. That's like if you gave yourself the options of "one hand behind your back" or "two hands behind your back" in a fight when we already knew how to fight with "zero hands behind your back".

But I'm not sure I even believe that, because the worst thing is dogmatism. Uncle Bob convinced young developers to be dogmatic.

I've dealt with code that was a mess with no adherence to rules. I've dealt with teams where everything need to be perfect. The first group shipped products. The second groups had neat looking code bases but had much more trouble shipping. Sometimes it was impossible to get in simple lines of code because it didn't match "the rules".


> I came away feeling like Uncle Bob is more interested in playing rhetorical judo than anything else

That's his only option.

I am not trying to speak ill of the man, but I am quite dubious of his advice.

I truly believe everyone has something to offer. However, I would feel more inclined to follow Uncle Bob's advice if he actually had the portfolio to back it up.

If Linus Torvalds were to give advice on how to build an operating system's kernel, I feel as though I should listen. Not only because Torvalds had/has good ideas, but because he also has demonstrable experience and work to back up his claims.

Uncle Bob has a lot of words, but projects speak louder.


> If Linus Torvalds were to give advice on how to build an operating system's kernel, I feel as though I should listen.

I'm pretty sure Linus' advice is 'don't be r***d'. In recent years he's learned a bit and now also would say 'don't be a c*t, probably, most of the time'. :P


You know what? That's still good advice. I think many should take it to heart.

>It is economically better for most organizations to conserve programmer cycles than computer cycles.

Yeah nah. At the rate that programs are getting worse, there’s simply no way that this is remotely true now, especially with cloud costs growing quite rapidly.


He's the son of a pastor, he's definitely interested in rhetorical judo.

tldr;

Premature optimization is the root of all evil. (Donald Knuth)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: