[HN Gopher] Clean Code vs. A Philosophy Of Software Design
       ___________________________________________________________________
        
       Clean Code vs. A Philosophy Of Software Design
        
       Author : recursivedoubts
       Score  : 424 points
       Date   : 2025-02-24 23:52 UTC (23 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | htk wrote:
       | What a great discussion between two prominent figures in the
       | field of software design. Thank you for posting this!
        
         | htk wrote:
         | You guys really hated that I found the discussion interesting?
        
           | throw16180339 wrote:
           | FWIW, me too comments are usually downvoted.
        
             | htk wrote:
             | Makes sense now, they don't add much, or anything. We
             | already have the upvote button for this.
        
           | kragen wrote:
           | It seemed like a content-free comment. I was no better
           | informed after reading it than before, and it was of no
           | artistic or cultural value. It did not induce me to question
           | any of my assumptions or investigate anything. It expressed
           | your experience, but your experience was not unusual or
           | surprising in any way, except perhaps that you did not know
           | that "Uncle" Bob Martin was an incompetent charlatan.
           | Possibly those were among the reasons people downvoted it.
        
             | htk wrote:
             | Fair points! Thank you.
        
           | wglb wrote:
           | Downvotes are a legitimate expression of disagreement, not
           | hate.
        
             | htk wrote:
             | "Hate" was too strong of a word to use.
        
       | ilrwbwrkhv wrote:
       | john ousterhout's book is the only book on how to write software
       | that has any actual evidence behind it. i highly recommend it as
       | the only book to read on how to write code. and uncle bob, well,
       | best to avoid his stuff as much as possible. clean code takes
       | away about 5 years from every dev's life as they think they need
       | to read it to become an intermediate developer and one they
       | realize that is not the way, can they finally grow.
        
         | owl_vision wrote:
         | 5 years is about right.
         | 
         | when i found a copy of clean code in a bookstore, it only took
         | me a few minutes to put it back. I had read John Ousterhout's
         | book prior.
        
         | pinoy420 wrote:
         | In typical HN commenter smugness. It took me less than that to
         | realise it was bullshit. It didn't make things clear, it made
         | them more abstract and more resistive to change. Similarly with
         | DDD. Just build what you need and deal with the consequences of
         | inevitable change later. No one cares if you miraculously
         | perfectly modelled your "definitely the final form" of your
         | domain from day 0.
         | 
         | Oh and TDD?! Ah yes those perfectly defined unit cases you
         | write for implementation details. The best comment I read
         | recently (sorry I can't find it) something akin to "The first
         | unit I write is to validate the intended side effects through
         | properly exercising associated mocks"
         | 
         | As with everything there is no "best way" to do something, but
         | in software engineering... there are far more bad "best ways"
         | than best "best ways"
        
           | rswail wrote:
           | DDD is a good way to extract the business logic from the
           | implementation.
           | 
           | By modelling the business you raise the business logic up to
           | a 1st class element.
           | 
           | By implementing the business objects you encapsulate their
           | functionality in the business.
           | 
           | The words "Account" or "Outstanding Balance" have business
           | meanings. Modelling them allows you to express the business
           | logic explicitly.
           | 
           | It also allows you to create tests that are related to that
           | business logic, not the implementation.
           | 
           | You can still "build what you need and deal with the
           | consequences of inevitable change later".
           | 
           | Model what you need to build, the business is going to have
           | to make changes to that model to implement their changes, IT
           | systems are a detail.
           | 
           | Change by extending and changing the DDD models.
           | 
           | To reverse the question, how do you write code that "does
           | what you need" _without_ understanding the domain?
        
         | ziml77 wrote:
         | That book really poisons the mind. Even if there's some good
         | things to learn in there, it's stashed among a lot of advice
         | that is either plain bad or needs asterisks. But there aren't
         | really any asterisks and instead it presents what look like
         | rules that you shouldn't be breaking if you want to be a good
         | programmer.
         | 
         | When I first read the book I'd already been programming for 10
         | years, but I was in my first job out of college. I'd heard a
         | lot about the book and so I trusted what it had to say. I let
         | it override how I would have written code because I figured
         | coding professionally was just far different than what I would
         | consider the best way to write code.
         | 
         | Interestingly, 5 years sounds about right for how long it took
         | me to finally start trusting my own judgement. I think it was a
         | combination of being more confident in myself but also because
         | I was doing larger projects and it was more frequent that I was
         | putting down a project and then coming back a couple months
         | later. That's how I was able to see how bad the code was to
         | work with once my mental model of it had flittered away.
         | 
         | Now I take a much less strict approach to my code and I find it
         | a lot better to work with later.
        
           | MobiusHorizons wrote:
           | > instead it presents what look like rules that you shouldn't
           | be breaking if you want to be a good programmer.
           | 
           | I see this a lot, especially among more junior programmers. I
           | think it likely stems from insecurity with taking
           | responsibility for making decisions that could be wrong. It
           | makes sense, but I can't help but feel it is failing to take
           | responsibility for the decisions that are the job of
           | engineering. Engineering is ultimately about choosing the
           | appropriate tradeoffs for a specific situation. If there was
           | a universally "best" solution or easy rule to follow, they
           | wouldn't need any engineers.
        
             | runevault wrote:
             | I always think of this as the programmer version of "No one
             | got fired for choosing IBM." that was a common phrase about
             | executives back in the day. Do the thing that you can just
             | point to "experts" and blame them.
        
               | MobiusHorizons wrote:
               | That is a helpful comparison. I guess it is risk aversion
               | at the core. At some point risk aversion becomes
               | abdication of decision making to others, which seems
               | broken in roles that are specifically hired for making
               | decisions, but that's even more true of executives.
        
               | runevault wrote:
               | I completely agree with you, mind I feel the same way
               | about the people who the original comment was talking
               | about. They are paid the big bucks to decide how to spend
               | money to optimize the company.
        
           | OnionBlender wrote:
           | Which book are you referring to? The parent comment mentioned
           | two books.
        
             | ziml77 wrote:
             | Clean Code
        
           | WalterBright wrote:
           | 1. newbie follows the rules because he is told to
           | 
           | 2. master follows the rules because he understands them
           | 
           | 3. guru breaks the rules because they don't apply
        
             | Cthulhu_ wrote:
             | There's a step between 1 and 2, someone who writes rules
             | because he _believes_ he understands them.
             | 
             | There was an era where every just-above-newbie PHP
             | developer would start writing their own authoritative blog
             | posts and frameworks, I strongly feel that had a big impact
             | on the fragmentation and reputation of the PHP ecosystem as
             | being insecure (because a lot of these authoritative blog
             | posts demonstrated how to introduce SQL injection
             | vulnerabilities)
        
         | chillpenguin wrote:
         | "john ousterhout's book is the only book on how to write
         | software that has any actual evidence behind it."
         | 
         | This is false and hopefully no one takes you seriously when
         | they read that. There are books about empirical methods for
         | software engineering, for example, which actually seek to find
         | real evidence for software engineering techniques. See Greg
         | Wilson's work, for example.
         | 
         | There are lots of other architecture/design books that use real
         | world systems as examples. "Evidence" is definitely lacking in
         | our field, but you can find it if you try.
        
           | recursivedoubts wrote:
           | > no links
        
           | froh wrote:
           | Greg Wilson indeed is tremendously helpful in facilitating
           | "the industry" to think about our craft:
           | 
           | https://github.com/gvwilson
           | 
           | edit: wow, in his project "It will never work in theory" he's
           | fairly sober about the ability of "the industry" to reflect
           | on "the craft"
           | 
           | https://neverworkintheory.org/
           | 
           | > about the project:
           | 
           | > People have been building complex software for over sixty
           | years, but until recently, only a handful of researchers had
           | studied how it was actually done. Many people had opinions--
           | often very strong ones--but most of these were based on
           | personal anecdotes or the kind of "it's obvious" reasoning
           | that led Aristotle to conclude that heavy objects fall faster
           | than light ones.
           | 
           | in the 2024 retrospective:
           | 
           | > Conclusion
           | 
           | > The comedian W.C. Fields once said, "If at first you don't
           | succeed, try, try again. Then quit. There's no point in being
           | a damn fool about it." Thirteen years after our first post,
           | it is clear that our attempts to bridge the gulf between
           | research and practice haven't worked. We look forward to
           | hearing what actionable plans others have that will find real
           | support from both communities.
        
             | WillAdams wrote:
             | The annals of the IEEE and ACM would argue against:
             | 
             | >only a handful of researchers had studied how it was
             | actually done
             | 
             | I am pretty sure that there are more than 5 references to
             | papers in APoSD.
        
       | zbentley wrote:
       | It's striking to me how out of touch Martin seems to be with the
       | realities of software engineering in this transcript. Stylistic
       | refactors that induce performance regressions, extremely long and
       | tortured method names for three-line methods, near-total animus
       | towards comments ... regardless of who is right/wrong about what,
       | those takes seem like sophomoric extremism at its worst, not
       | reasoned pragmatism that can be applied to software development
       | in the large.
       | 
       | When I encounter an Uncle Bob devotee, I'm nearly always
       | disappointed with the sheer _rigidity_ of their approach:
       | everything must be reduced thus, into these kind of pieces,
       | because it is Objectively Better software design, period. Sure,
       | standard default approaches and best practices are important
       | things to keep in mind, but the amount of _dogma_ displayed by
       | folks who like Martin is really shocking and concerning.
       | 
       | I worry that his approach allows a certain kind of programmer to
       | focus on like ... aesthetic, dogmatic uniformity (and the
       | associated unproductivity of making primarily aesthetically-
       | motivated, dogmatic changes rather than enhancements, bugfixes,
       | or things that other coders on a project agree improves
       | maintainability) instead of increasing their skills and
       | familiarity with their craft.
       | 
       | Maintainability/appropriate factoring are subjective qualities
       | that depend a lot on the project, the other programmers on it,
       | and the expectations around how software engineering is done in
       | that environment.
       | 
       | Pretending that's not true--that a uniform "one clean code style
       | to rule them all" is a viable approach--does everyone involved a
       | disservice. Seasoned engineers trying to corral complexity, new
       | engineers in search of direction and rigor, customers waiting for
       | engineering to ship a feature, business stakeholders confused as
       | to why three sprints have gone by with "refactor into smaller
       | methods" being the only deliverable--everyone.
        
         | frozenlettuce wrote:
         | I don't know why people take UB seriously. He never provided
         | proof of any work experience - he claims to have worked for
         | just a single company that... never shipped any code into
         | production. Even his code examples on GitHub are just snippets,
         | not even a to-do app (well, I think that his style of "just one
         | thing per function" works as a self-fulfilling prophecy).
         | 
         | Maybe people like him are the reason why we have to do leet
         | code tests (I don't believe he would be capable of solving even
         | an easy problem).
        
           | rester324 wrote:
           | Uncle Bob is one of the core contributors to Fitnesse, which
           | had moderate success in the Java popularity era back in the
           | day.
           | 
           | Also, you do understand that people worked as software
           | engineers even before Github became popular, or open sourcing
           | to begin with, do you? So if someone is 60+ year old, chances
           | are that most of his work has never been open sourced, and
           | his work was targeting use cases, platforms, services which
           | have no utility in this age any more.
           | 
           | Which have all nothing to do with how good a software
           | engineer someone is.
           | 
           | And finally, do you have any proof that he never shipped any
           | code into production?
        
             | zabzonk wrote:
             | > So if someone is 60+ year old, chances are that most of
             | his work has never been open source
             | 
             | Somewhat ageist? I'm 72 and have produced a number of FOSS
             | tools.
        
               | sebmellen wrote:
               | Truly. I know plenty of people in their 60s and 70s who
               | use Git and are still very sharp programmers.
        
               | kragen wrote:
               | Using Git is unrelated to whether the software you write
               | is proprietary or open-source.
        
             | fourside wrote:
             | The criticism was that UB worked at a company that
             | allegedly didn't ship code to production, not that he
             | doesn't have a corpus of open source projects on GitHub.
        
             | imjonse wrote:
             | > So if someone is 60+ year old, chances are that most of
             | his work has never been open sourced,
             | 
             | John Ousterhout is 70 years old and one of the open source
             | pioneers. We don't know what Uncle Bob shipped or did not
             | ship but his friendly opponent in this discussion
             | definitley did ship high profile projects.
        
             | ahoka wrote:
             | Do you mean commits to the project like this crap: https://
             | github.com/unclebob/fitnesse/commit/d6034080a04c740c...
             | 
             | This level of pointless obfuscation would not survive a
             | code review at any sane dev team.
        
               | frozenlettuce wrote:
               | It's the kind of commit that you get from someone that
               | wants to look productive but is just renaming variables
               | in their IDE.
        
         | NomDePlum wrote:
         | I'm going to have to admit to never having read Clean Code.
         | It's just never appealed to me. I did read some of UBs articles
         | a fair number of years ago. They did make me think - which I'd
         | say is a positive and along the lines you are putting forwards.
         | 
         | Rigidity and "religious" zeal in software development is just
         | not helpful I'd agree.
         | 
         | I do however love consistency in a codebase, a point discussed
         | in "Philosophy of Software Design", I always boil this down to,
         | even if I'm doing something wrong, or suboptimal, if I do it
         | consistently, once I realise, or it matters I only have one
         | thing to change to get the benefit.
         | 
         | It's the not being able to change regardless, in the face of
         | evidence, that separates consistency and rigidity (I hope)!
        
         | the__alchemist wrote:
         | I'm not familiar with the _Clean Code_ book etc; my
         | introduction is the article. UB seems to be advocating
         | consistently for patterns that are not my cup of tea! For
         | example: Functions sometimes make sense as 2-3 lines. Often
         | 5-20. Less often, but not rarely, much more than that!
         | 
         | I'm also a fan of detailed _doc_ comments on every module and
         | function, and many fields /variants as well. And, anything that
         | needs special note, is unintuitive, denotes units or a source
         | etc.
        
           | milesrout wrote:
           | Function length also depends on language. Every line of one
           | language requires three line in another if the former has
           | implicit error handling and the latter explicit. But I find
           | the cognitive load of the two to be similar.
           | 
           | I am also okay with 1000 line functions where appropriate.
           | Making me jump around the code instead of reading one line at
           | a time, in a straight line? No thanks!
        
           | waynesonfire wrote:
           | The issue that of function length is irrelevant and
           | incidental. Keep paying attention to what UB is saying.
        
             | the__alchemist wrote:
             | I didn't get that impression from reading it. I also find
             | the TDD approach discussed to be high inertia.
        
         | hakunin wrote:
         | Another example of not quite pragmatic advice is Screaming
         | Architecture. If you take some time to think about it, it's
         | actually not a good idea. One of the blog posts I'm working on
         | is a counter argument to it.
        
           | edwardsdl wrote:
           | I'd love for you to expand on this!
        
             | hakunin wrote:
             | Short version: when designing new software, you don't have
             | its architectural picture in the beginning. So when
             | starting from scratch, the architecture shouldn't be
             | screaming, but rather, it has to be non-committal/non-
             | speculative to allow wiggle room for the future. (How to
             | achieve non-committal architecture is the biggest topic I'm
             | interested in, and I find 1 good tactic every few years).
             | Specifically, the architecture should ephasize entry points
             | and outputs. That's exactly what frameworks like Rails
             | provide. You go by entry points until some sort of custom
             | architecture starts emerging from the middle, which is when
             | it can slowly begin "screaming" over time.
        
         | aprilthird2021 wrote:
         | I read Clean Code when I started out my career and I think it
         | was helpful for a time when I worked on a small team and we
         | didn't really have any standards or care about maintainability
         | but were getting to the point where it started mattering.
         | 
         | Sure, dogmatism is never perfect, but when you have nothing, a
         | dogmatic teacher can put you in a good place to start from. I
         | admired that he stuck to his guns and proved that the rules he
         | laid out in clean code worked to make code more readable in
         | lots of situations.
         | 
         | I don't know anything about him as a person. I never read his
         | other books, but I got a lot out of that book. You can get a
         | lot out of something without becoming a devotee to it.
         | 
         | EDIT: I think even UB will agree with me that his dogmatism was
         | meant as an attitude, something strong to hit back against a
         | strong lack of rigidity or care about readable code, vs a
         | literal prescription that must be followed. See his comment
         | here:
         | 
         | > Back in 2008 my concern was breaking the habit of the very
         | large functions that were common in those early days of the
         | web. I have been more balanced in the 2d ed.
         | 
         | And maybe I was lucky, but my coding life lined up pretty
         | neatly with the time I read Clean Code. It was an aha moment
         | for me and many others. For people who had already read about
         | writing readable code, I'm sure this book didn't do much for
         | them.
        
         | hansvm wrote:
         | > sheer rigidity
         | 
         | That looks more like a communication style difference than
         | anything else. Uncle Bob's talks and writing are prescriptive
         | -- which is a style literally beaten into me back when I was in
         | grade school, since it's implied just from the fact that it's
         | you doing the speaking that you're only describing your
         | opinions and that any additional hedging language weakens your
         | position further than you actually intend.
         | 
         | If you listen to him in interviews and other contexts where
         | he's explicitly asked about dogmatism as a whole or on this or
         | that concept, he's very open to pragmatism and rarely needs
         | much convincing in the face of even halfway decent examples.
         | 
         | > animus toward comments
         | 
         | Speaking as someone happy to drop mini-novels into the tricky
         | parts of my code, I'll pick on this animus as directionally
         | correct advice (so long as the engineer employing that advice
         | is open to pragmatism).
         | 
         | For a recent $WORK example, I was writing some parsing code and
         | had a `populate` method to generate an
         | object/struct/POCO/POJO/dataclass/whatever-it-is-in-your-
         | language, and as it grew in length I started writing some
         | comments describing the sections, which for simplicity's sake
         | we'll just say were "populate at just this level" and
         | "recurse."
         | 
         | If you take that animus toward comments literally, you'll
         | simply look at those comments and say they have to be removed.
         | I try to be pragmatic, and I took it as an opportunity to check
         | if there was some way to make the code more self-evident. As
         | luck would have it, simply breaking that initial section into a
         | `populate_no_recurse` method created exactly the documentation
         | I was looking for and also wound up being helpful as a
         | meaningful name for an action I actually wanted to perform in a
         | few places.
         | 
         | That particular pattern (breaking a long method into a sequence
         | of named intermediate parts) has failure modes, especially in
         | the hot path in poorly optimized runtimes (C#, Java, ...,
         | Python, ...), and definitely in future readability if employed
         | indiscriminately, but I have more than enough experience to be
         | confident it was a good choice here. The presence in my mind of
         | some of Uncle Bob's directionally correct advice coloured how I
         | thought about my partial solution and made it better.
         | 
         | > other animus
         | 
         | - Stylistic refactors that induce performance regressions can
         | be worth it. As humans, we're pre-disposed to risk avoidance,
         | so let's look at an opposite action with an opposite effect:
         | How often are you willing to slow down feature velocity AND
         | make the code harder to maintain just to squeeze out some
         | performance (for a concrete example, suppose there's some
         | operation with space/time/bandwidth tradeoffs which imply you
         | should have a nasty recursive cte in your database to compute
         | something like popcount on billion-bit-masks, or even better
         | just rewrite that portion of the storage layer)? My job is 80%
         | making shit faster and 10% teaching other people how to make
         | shit faster, but there are only so many hours in the day. I
         | absolutely still trade performance for code velocity and
         | stability from time to time, and for all of those fledgeling
         | startups with <1M QPS they should probably be making that trade
         | more than I do (assuming it's an actual trade and not just an
         | excuse for deploying garbage to prod).
         | 
         | - The "tortured method names" problem is the one I'm most on
         | the fence about. Certainly you shouldn't torture a long name
         | out of the ether if it doesn't fit well enough to actually give
         | you the benefits of long names (knowing what it does from its
         | name, searchability), but what about long names which do fit?
         | For large enough codebases I think long names are still worth
         | the other costs. It's invaluable to be able to go from some
         | buggy HTML on some specific Android device straight to the one
         | line in a billion creating the bug, especially after a couple
         | hiring/firing sessions and not having anybody left who knows
         | exactly how that subsystem works. I think that cutover point is
         | pretty high though. In the 100k-1M lines range there just
         | aren't enough similar concepts for searchability to benefit
         | much from truly unique names, so the only real benefit is
         | knowing what a thing does just from its name. The cost for long
         | names is in information density, and when it's clear from
         | context (and probably a comment or three) I'm fine writing a
         | numeric routine with single-letter variable names, since to do
         | otherwise would risk masking the real logic and preventing the
         | pattern-recognition part of your brain from being able to help
         | with matters. HOWEVER, names which properly tell you what a
         | thing does are still helpful (the difference between calling
         | `.resetRetainingCapacity()` and `.reset()` -- the latter you
         | still have to check the source to see if it's the method you
         | want, slowing down development if you're not intimately
         | familiar with that data structure). I still handle this piece
         | of advice on a case-by-case basis, and I won't necessarily
         | agree with my past self from yesterday.
         | 
         | > "Uncle Bob devotees" vs "Uncle Bob"
         | 
         | This is maybe the core of your complaint? I _have_ met a lot of
         | people who like his advice and aren't very pragmatic with it.
         | Most IME are early-career and just trying to figure out how to
         | go from "I can code" to "I can code well," and can therefore be
         | coached if you have well-reasoned counter-examples. Most of the
         | rest IME like Uncle Bob's advice but don't code much, and so
         | their opinions are about as valuable as any other uninformed
         | opinion, and I'm not sure I'd waste too much time lamenting
         | that misinformation. For the rest of the rest? I don't have a
         | large enough sample I've interacted with to be very helpful,
         | but unrelenting dogmatism is pretty bad, and people like that
         | certainly exist.
        
           | zbentley wrote:
           | Thanks for the thoughtful response. I generally don't want to
           | get into the _specifics_ of what Martin advocates for.
           | Whether to prefer or eschew comments, give methods a
           | particular kind of names, accept a performance penalty for a
           | refactor--those are all things that are good or bad in
           | context.
           | 
           | I think a lot of engineers hear "there's a time and a place"
           | or "in context" and assume that I'm saying that the approach
           | to coding can or should differ between _every contribution_
           | to a codebase. Not so! It 's very important to have default
           | approaches to things like comments, method length, coupling,
           | naming, etc. The default approach that makes the most sense
           | is, however, bounded by _context_ , not Famous Author's One
           | True Gospel Truth (or, in many cases, Change-Averse Senior
           | Project Architect's One True Gospel Truth). The "context
           | boundary" for a set of conventions/best practices is usually
           | a codebase/team. Sometimes it's a sub-area within a codebase.
           | More rarely, it's a type of code being worked on (e.g.
           | payment processing code merits a different approach from
           | kleenex/one-off scripts). Within those context boundaries,
           | it's _absolutely_ appropriate to question when contributors
           | deviate from an agreed-upon set of best practices--they just
           | might not be Martin 's best practices.
           | 
           | Rather, the core of my critique is that Martin's approach
           | lacks _perspective_. Perspective /pragmatism--not some
           | abstract notion of "skill level in creating well-factored
           | code according to a set of rules"--is the scarce commodity
           | among the intermediate-seeking-senior engineers that Martin's
           | work is primarily marketed toward and valued by.
           | 
           | From there, I see two things wrong with Martin's stance in
           | the Osterhout transcript:
           | 
           | "Out of touch" was not an arbitrarily chosen ad-hominem. When
           | Osterhout pressed Martin to improve and work on some code,
           | Martin's output and his defense of it were really low-
           | quality. I can tell they're really low quality because, in
           | spite of differing _specific_ opinions on things like method
           | length /naming/SRP, almost everyone here and to whom I've
           | showed that transcript finds _something_ seriously wrong with
           | Martin 's version, while the most stringent critique of
           | Osterhout's code I've seen mustered is "eh, it's fine, could
           | be better". That, and Martin's statements around the "why" of
           | his refactors, indicate that the applicability of his advice
           | for material code quality improvements in 2025 (as opposed
           | to, say, un-spaghettification of 2005 PHP 5000-line god-
           | object monstrosities) is in doubt. On its own, that in-
           | applicability wouldn't be a massive problem, which brings me
           | to...
           | 
           | Second, Martin is a teacher. When you mention '"Uncle Bob
           | devotees" vs "Uncle Bob"' and I talk about the _rigidity_ I
           | see in evidence among people that like Martin, I 'm talking
           | about him as a teacher. This isn't a Torvalds or Antirez or
           | Fabrice Bellard-type legendary contributor discussing
           | methodological approaches that _worked for them_ to make
           | important software. Martin is first and foremost (and perhaps
           | solely) a teacher: that 's how he markets himself and what
           | people value him for. And that's OK! Teachers do not have to
           | be contributors/builders to be great teachers. However, it
           | does mean that we get to evaluate Martin based on the
           | _quality of his pedagogical approach_ rather than holding the
           | ideas he teaches on their own merit alone. Put another way,
           | teachers say half-right things all the time as a means of
           | saving students from things they 're not ready for, and we
           | don't excoriate them for that--not so long as the goal of
           | preparing the students to understand the material in general
           | (even if some introductory shortcuts need to later be
           | uninstalled) is upheld.
           | 
           | I think Martin has a really poor showing as a teacher. The
           | people his work resonates the most strongly with are the
           | people who take it to the most rigid, unhealthy extremes. His
           | instructorial tone is absolute, interspersed with a few
           | "...but only do this pragmatically of course" interjections
           | that he himself doesn't really seem to believe. His material
           | is often considered, in high-performing engineering
           | departments, to be something that leaders have to check back
           | against being taken too far rather than something they're
           | happy to have juniors studying. Those things speak to
           | failures _as a teacher_.
           | 
           | Sure, software engineers are often binary thinkers prone to
           | taking things to extremes--which means that a widely regarded
           | teacher of that crowd is obligated to take those tendencies
           | into account. Martin does not do this well: he proposes dated
           | and inappropriate-in-many-cases practices, while modeling a
           | stubborn, absolutist tone in his instruction and responses to
           | criticism. Even if I were to give his specific technical
           | proposals the greatest possible benefit of the doubt, this is
           | still bad pedagogy.
        
         | valenterry wrote:
         | > It's striking to me how out of touch Martin seems to be with
         | the realities of software engineering in this transcript
         | 
         | It was always like that. And Fowler the same thing with his
         | criticism of anemic domain model. But software-engineering is
         | no exceptions to having a mass of people believing someone
         | without thinking by themselves.
        
           | motorest wrote:
           | > It was always like that. And Fowler the same thing with his
           | criticism of anemic domain model.
           | 
           | What leads you to disagree with the fact that anemic domain
           | models are an anti-pattern?
           | 
           | https://martinfowler.com/bliki/AnemicDomainModel.html
           | 
           | I think it's obvious that his critique makes sense if you
           | actually take a moment to try learn and understand what he
           | says and where he comes from. Take a moment to understand
           | what case he makes: it's not object-oriented programming.
           | That's it.
           | 
           | See,in a anemic domain model, instead of objects you have
           | DTOs that are fed into functions. That violates basic tenners
           | of OO programming. It's either straight up procedural
           | programming or, if you squint hard enough, functional
           | programming. If you focus on OO as a goal, it's clearly an
           | anti-pattern.
           | 
           | His main argument is summarized in the following sentence:
           | 
           | > _In essence the problem with anemic domain models is that
           | they incur all of the costs of a domain model, without
           | yielding any of the benefits._
           | 
           | Do you actually argue against it?
           | 
           | Listen, people like Fowler and Uncle Bob advocate for
           | specific styles. This means they have to adopt a rethoric
           | style which focuses on stressing the virtues of a style and
           | underlining the problems solved by the style and created by
           | not following the style. That's perfectly fine. It's also
           | fine if you don't follow something with a religious fervor.
           | If you have a different taste, does it mean anyone who
           | disagrees with you is wrong?
           | 
           | What's not cool is criticizing someone out of ignorance and
           | laziness, and talking down on someone or something just
           | because you feel that's how your personal taste is valued.
        
             | overgard wrote:
             | "It's not object oriented programming" is only a good case
             | to make if you think object oriented programming is
             | synonomous with good. I don't think that's true. It's
             | sometimes good, often not good.
             | 
             | Why would focusing on OO be a goal? The goal is to write
             | good software that can be easily maintained. Nobody outside
             | of book writers are shipping UML charts
        
               | rester324 wrote:
               | Why would you not focus on writing OO code in an OO
               | language for example? Would you start writing OO code in
               | a functional langugage? No you wouldn't, because it would
               | be pointless. There are programming paradigms for a
               | reason
        
               | brodo wrote:
               | > Why would you not focus on writing OO code in an OO
               | language for example?
               | 
               | Often people do this to deliver higher quality software.
               | Most languages still have some OO features, and people
               | don't use them because they know they lead to bad code.
               | Inheritence (a core OO feature) comes to mind. Most
               | professionals nowadays agree that it should not be used.
               | 
               | OO designs are often over-abstracted which makes them
               | hard to understand and hard to change. They lack
               | "locality of behavior". Trivial algorithms look
               | complicated because parts of them are strewn across
               | several classes. This is why more modern langues tend to
               | move away from OOP.
               | 
               | My guess is that im the long term, what we will keep from
               | OO is the possibility to associate methods with structs.
        
               | lmm wrote:
               | > Why would you not focus on writing OO code in an OO
               | language for example?
               | 
               | That's circular logic. I wouldn't focus on writing OO
               | code because I know from experience that the result is
               | usually worse. If I had to use a language that was
               | oriented towards writing OO code, I'd still try to limit
               | the damage.
               | 
               | > There are programming paradigms for a reason
               | 
               | Nah. A lot of them are just accidents of history.
        
               | wglb wrote:
               | > Why would you not focus on writing OO code in an OO
               | language
               | 
               | It should be the best solution to the problem direct
               | whether or not use of OO is best, not the language.
        
               | throw16180339 wrote:
               | > Why would you not focus on writing OO code in an OO
               | language for example? Would you start writing OO code in
               | a functional language? No you wouldn't, because it would
               | be pointless. There are programming paradigms for a
               | reason
               | 
               | I'm paid for efficiently solving business problems with
               | software, not using a particular paradigm. If an FP
               | solution is more appropriate and the team can support it,
               | then that's what I'll use.
        
               | motorest wrote:
               | > "It's not object oriented programming" is only a good
               | case to make if you think object oriented programming is
               | synonomous with good. I don't think that's true. It's
               | sometimes good, often not good.
               | 
               | See, this is the sort of lazy ignorance that adds nothing
               | of value to the discussion, and just reads as spiteful
               | adhominems.
               | 
               | Domain models are fundamentally an object-oriented
               | programming concept. You model the business domain with
               | classes, meaning you specify in them the behavior that
               | reflects your business domain. Your Order class has a
               | collection of Product items, but you can update an order,
               | cancel a order, repeat an order, etc. This behavior
               | should be member functions. In Domain-Driven design, with
               | its basis on OO, you implement these operations at the
               | class level, because your classes model the business
               | domain and implement business rules.
               | 
               | The argument being made against anemic domain models is
               | that a domain model without behavior fails to meet the
               | most basic requirements of a domain model. Your domain
               | model is just DTOs that you pass around as if the were
               | value types, and have no behavior at all. Does it make
               | sense to have objects without behavior? No, not in OO and
               | elsewhere as well. Why? Because a domain model without
               | behavior means you are wasting all development effort
               | building up a structure that does nothing and adds none
               | of the benefits, and thus represents wasted effort. You
               | are better off just doing something entirely different
               | which is certainly not Domain-Driven design.
               | 
               | In fact, the whole problem with the blend of argument you
               | are making is that you are trying to push a buzzword onto
               | something that resembles none of it. It's like you want
               | the benefit of playing buzzword bingo without even
               | bothering to learn the absolute basics of it, or anything
               | at all. You don't know what you're doing, and somehow
               | you're calling it Domain-Driven design.
               | 
               | > Why would focusing on OO be a goal?
               | 
               | You are adopting a OO concept, which the most basic
               | traits is that it models business domains with objects.
               | Do you understand the absurdity of this sort of argument?
        
               | valenterry wrote:
               | > Domain models are fundamentally an object-oriented
               | programming concept
               | 
               | They are absolutely not. In fact, they are not even
               | specific to even just programming, let alone OOP.
        
               | lmm wrote:
               | > Domain models are fundamentally an object-oriented
               | programming concept.
               | 
               | They are not.
               | 
               | > You model the business domain with classes, meaning you
               | specify in them the behavior that reflects your business
               | domain.
               | 
               | I have better tools for doing that.
               | 
               | > In Domain-Driven design, with its basis on OO, you
               | implement these operations at the class level, because
               | your classes model the business domain and implement
               | business rules.
               | 
               | You're still not explaining the "why". You're just
               | repeating a bunch of dogma.
               | 
               | > a domain model without behavior means you are wasting
               | all development effort building up a structure that does
               | nothing and adds none of the benefits, and thus
               | represents wasted effort.
               | 
               | I know from experience that this is completely false.
               | 
               | > You don't know what you're doing, and somehow you're
               | calling it Domain-Driven design.
               | 
               | I don't call it domain-driven. You can call it domain-
               | driven if you want, or not if you don't want. I don't
               | care what it's called, I care whether it results in
               | effective, maintainable software with low defect rates.
        
               | wglb wrote:
               | > I care whether it results in effective, maintainable
               | software with low defect rates.
               | 
               | This is what it is about. All the other things that have
               | been invented need to be in service of this goal.
        
               | mrkeen wrote:
               | > Your Order class has a collection of Product items, but
               | you can update an order, cancel a order, repeat an order,
               | etc. This behavior should be member functions.
               | 
               | This is how to fuck up OO and give it a bad name:
               | order.update(..) // Now your Order knows about the
               | database.            order.cancel(..) // Now your Order
               | can Email the Customer about a cancellation.
               | order.repeat(..) // Now your Order knows about the
               | Scheduler.
               | 
               | What else could Order know about? Maybe give it a JSON
               | renderer .toJson(), a pricing mechanism .getCost(),
               | discounting rules .applyDiscount(), and access to
               | customer bank accounts for .directDebit(); Logging and
               | backup too. And if a class has 10+ behaviours you've
               | probably forgotten 5 more.
               | 
               | An Order is a piece of paper that arrived in your
               | mailbox. You can't take a sharpie to it, you can't tell
               | it to march itself into the filing cabinet. It's a piece
               | of paper which _you.read()_ so that _you.pack()_
               | something into a box and take it to the post office.
               | _You_ have behaviours and _the post office_ has
               | behaviours. The Order and the Box do not. At best they
               | have a few getters() or some mostly-static methods for
               | returning aggregate data - but even then I 'd probably
               | steer clear. For instance: if the Order gave me a nice
               | totalPrice() method, it simplifies things for later
               | right? Well no, because in TaxCalculator (not
               | order.calculateTax()) I will want to drill down into the
               | details, not the aggregate. Likewise for DiscountApplier.
               | 
               | > Does it make sense to have objects without behavior?
               | No, not in OO and elsewhere as well.
               | 
               | It does, just like in the Domain (real-world Orders).
               | Incidentally, I believe objects-without-behaviours is one
               | of the core Clojure tenets.
               | 
               | Since this is HN's monthly UB-bashing thread, I should
               | point out that I learnt most of this stuff from him.
               | (It's more from SOLID though, I don't think I have much
               | to say on about cleanliness.)
               | 
               | The above examples violate SRP and DI.
               | 
               | "Single reason to change": If order.cancel(..) knows
               | about email, then this is code I have to change _if the
               | cancellation rules change_ or _if the email system
               | changes_. What if we don 't notify over email anymore?
               | Order has to become aware of SMS or some other tech which
               | will cause more reasons for change.
               | 
               | "Dependency inversion": People know what Orders are,
               | regardless of technical competence. They can exist
               | without computers or any particular implementation. They
               | are therefore (relative to other concerns here) _high-
               | level_ and _abstract_. Orders are processed using a
               | database, Kafka and /or a bunch of other technologies (or
               | _implementation details_ ). DI states that abstract
               | things should not depend on concrete things.
        
               | valenterry wrote:
               | Aw, you described it so much nicer than me. I feel bad
               | now.
        
               | Kerrick wrote:
               | We have a disagreement about the core of OOP. In English,
               | a simple sentence like "The cat eats the rat" can be
               | broken down as follows:
               | 
               | - Cat is the subject noun
               | 
               | - Eats is the verb
               | 
               | - Rat is the object noun
               | 
               | In object-oriented programming, the subject is most often
               | the programmer, the program, the computer, the user
               | agent, or the user. The object is... the object. The verb
               | is the method.
               | 
               | So, imagine the sentence "the customer canceled the
               | order."
               | 
               | - Customer is the subject noun
               | 
               | - Canceled is the verb
               | 
               | - Order is the object noun
               | 
               | In OOP style you do not express this as
               | customer.cancel(order) even though that reads aloud left-
               | to-right similarly to English. Instead, you orient the
               | expression around the object. The order is the object
               | noun, and is what is being canceled. Thus,
               | order.cancel(). The subject noun is left implicit,
               | because it is redundant. Nearly every subject noun in a
               | given method (or even system) will be the same
               | programmer, program, computer, user agent, or user.
               | 
               | For additional perspectives, I recommend reading Part I
               | of "Object-Oriented Analysis and Design with
               | Applications" (3rd edition) by Grady Booch et. al, and
               | "Object Thinking" by David West.
               | 
               | ---
               | 
               | That said, I think you're right about the single
               | responsibility principle in this example. A class with
               | too many behaviors should usually be decomposed into
               | multiple classes, with the responsibilities distributed
               | appropriately. However, the object should not be left
               | behavior-less. It must still be an anthropomorphized
               | object that encapsulates whatever data it owns with
               | behavior.
        
               | valenterry wrote:
               | > So, imagine the sentence "the customer canceled the
               | order."
               | 
               | > - Customer is the subject noun
               | 
               | And this is wrong. Because the customer did not cancel
               | the order. The customer actually _asked_ for the order to
               | be canceled. And the order was then canceled by  "the
               | system". Whatever that system is.
               | 
               | And that is the reason why it is not expressed as
               | customer.cancel(order) but rather system.cancel(order,
               | reason = "customer asked for it").
               | 
               | > Thus, order.cancel(). The subject noun is left
               | implicit, because it is redundant.
               | 
               | Ah, is that so? Then, I would like you to tell me: what
               | happens if there are two systems (e.g. a legacy system
               | and a new system, or even more systems) and the order
               | needs to be sometimes cancelled in both, or just one of
               | those systems? How does that work now in your world?
        
               | Kerrick wrote:
               | > The customer actually asked for the order to be
               | canceled.
               | 
               | This is why many object-oriented programmers prefer to
               | talk about message passing instead of method calling. It
               | is indeed about asking for the order to be canceled, and
               | the order can decide whether to fulfill that request.
        
               | projektfu wrote:
               | mrkeen mentioned dependency inversion (DI). I think it
               | makes sense in oop for an order to have a cancel method,
               | but the selection of this method might be better as
               | something configured with DI. This is because the caller
               | might not be aware of everything involved, as well.
               | 
               | If the system is new and there's only one way to do it,
               | it's not worth sweating over it. But if a new requirement
               | comes up it makes sense to choose a way to handle that.
               | 
               | For example, an order may be entered by a salesperson or
               | maybe by a customer on the web. The cancellation process
               | (a strategy, perhaps) might be different. Different users
               | might have different permissions to cancel one order or
               | another. The designer of the website probably shouldn't
               | have to code all that in, maybe they just should have a
               | cancel function for the order and let the business logic
               | handle it. Each order object could be configured with the
               | correct strategy.
               | 
               | If you don't want to use OO, that's fine, but you still
               | have to handle these situations. In what module do you
               | put the function the web designer calls? And how do you
               | choose the right process? These patterns will perhaps
               | have other names in other paradigms but the model is
               | effectively the same. The difference is where you stuff
               | the complexity.
        
               | mrkeen wrote:
               | The comparison to English grammar is unnecessary. I
               | didn't use it in my argument and you said it doesn't work
               | that way either, so when you arrive at
               | 
               | > The order is the object noun, and is what is being
               | canceled. Thus, order.cancel()
               | 
               | You've just restated the position I argued against,
               | without an argument.
        
             | valenterry wrote:
             | > it's not object-oriented programming. That's it.
             | 
             | Yes, exactly. And this "classical" object-oriented
             | programming is an anti-pattern _itself_.
             | 
             | (That being said, OOP is not well defined. And, for
             | example, I have nothing against putting related data
             | structures and functionality into the same namespace. But
             | that's not what OOP means to him here)
        
               | valenterry wrote:
               | I'll reply here with a very quick example why the anemic
               | domain model is superior in general, no matter if you do
               | OOP or anything else.
               | 
               | You used the example of an "order" yourself, so I'll
               | built upon it.
               | 
               | I would never combine functionality to update an order
               | with the data and structure of the an order. The reason
               | is simple: the business constraints _don 't always live
               | inside the order_.
               | 
               | Here's an example why such an approach inevitably must
               | fail: if the business says that orders can only be made
               | until 10000 items have been ordered in a month, then you
               | cannot model that constraint _inside_ of the order class.
               | You _must_ move it outside - to the entity that knows
               | about _all_ the orders in the system. That would be the
               | OrderRepository or however you want to call it.
               | 
               | Remember, here is what you said in your other post:
               | 
               | > Your Order class has a collection of Product items, but
               | you can update an order, cancel a order, repeat an order,
               | etc. This behavior should be member functions.
               | 
               | So your Order should have a repeat function? But how can
               | the order know if it can be repeated? It might violate
               | the max-monthly-items constraint. The only way for the
               | Order to do it is to _hold a reference to the
               | OrderRepository_.
               | 
               | And this is a big problem. You have now entangled the
               | concept of an OrderRepository and of an Order. In fact,
               | Orders could totally live without an OrderRepository
               | alltogether, for example when you build an
               | OrderSimulation where no orders are actually being
               | executed/persisted. But to do so, now you have this
               | OrderRepository, even if you don't need it.
               | 
               | The rule of the thumb is: if the business says "we don't
               | need feature A anymore, remove it" then you should be
               | able to remove that feature from the code _without
               | touching any unrelated feature_. If you now remove the
               | OrderRepository and cause a bug in the Order class due to
               | your code changes, the business will probably wonder how
               | that could be, because while the OrderRepository cannot
               | exist without Orders, Orders can exist without an
               | OrderRepository.
               | 
               | And if that seems a bit unrealistic, think of users: A
               | user can easily exist without a UserRepository, but not
               | the other way around.
               | 
               | That makes clear, that you the rich domain model is an
               | unsuitable and generally suboptimal solution to modeling
               | the domain of a business. The anemic domain model on the
               | other hand matches it perfectly.
               | 
               | And one more thing: even natural language disagrees with
               | the rich domain model. Does _an order repeat itself_? No!
               | An order _is repeated_ and that is, it is repeated _by
               | something or someone_. This alone makes clear that there
               | is an entity beyond the Order that is responsible for
               | such action. And again, the anemic domain model is a
               | great solution for expressing this in code.
               | 
               | But if you disagree, I'd like you to explain what you
               | believe the disadvantages of the anemic domain model are.
        
               | Kinrany wrote:
               | Links to any existing articles on this topic would be
               | greatly appreciated.
        
               | valenterry wrote:
               | This is the original article from Fowler:
               | https://martinfowler.com/bliki/AnemicDomainModel.html
               | 
               | By searching for that term, you'll easily find lots of
               | other takes on the matter.
        
               | Kinrany wrote:
               | > I'll reply here with a very quick example why the
               | anemic domain model is superior in general, no matter if
               | you do OOP or anything else.
               | 
               | I can search for it of course but results that aren't
               | about OOP purism appear to be rare.
        
               | mrkeen wrote:
               | I highly recommend a video if you don't mind the format:
               | https://youtu.be/zHiWqnTWsn4?t=3134
               | 
               | The slide at 52:14 is on the SOLID principles, the first
               | one is on SRP which gives pretty understandable advice
               | about whether Order should have behaviours.
        
               | samiv wrote:
               | You made a great example here and I absolutely agree with
               | you.
               | 
               | In fact I find this type of accidental / unneeded
               | coupling is the number one cause of problems, bugs and
               | limitations of re-use and thus development velocity in
               | any software product. Concepts where a single way
               | dependency is turned into a cycling dependency are really
               | hard to evolve, maintain, test and understand.
               | 
               | In fact I'd go as far as to say that as a general rule of
               | thumb if you have a situation where your class A depends
               | on class B that depends on class A you've made a big doo
               | doo and you should really seriously re-consider your
               | design.
               | 
               | (Adjacent to this rule is that classes that exist in the
               | same level of of the software hierarchy and are thus
               | siblings should also not know about each other).
               | 
               | In fact when you structure your code so that the
               | dependencies only go one way you end up with a neat
               | lasagna code base and everything can easily slotted in.
               | (Combined with this a secondary feature which is to
               | eliminate all jumps upwards in the stack, i.e. callbacks)
        
         | overgard wrote:
         | I haven't seen a lot of evidence that Martin really has the
         | coding chops to speak as authoritatively as he does. I think
         | when you become famous for giving advice or being an "expert",
         | it can be difficult to humble yourself enough to learn new
         | things. I know personally I've said a lot of dumb things about
         | coding in the past; luckily none of those things were codified
         | into a "classic" book.
         | 
         | What strikes me about the advice in Clean Code is that the
         | ideas are, at best, generally unproven (IE just Martin's
         | opinion), and at worst, justify bad habits. Saying "I don't
         | need to comment my code, my code speaks for itself" is
         | alluring, but rarely true (and the best function names can't
         | tell you WHY a function/module is the way it is.) Chopping up
         | functions and moving things around looks and feels like work,
         | except nothing gets done, and frankly often strikes me as being
         | the coding equivalent of fidget spinners (although at least
         | fidget spinners dont screw up your history). Whenever Martin is
         | challenged on these things he just says to use "good
         | judgement", but the code and advice is supposed to demonstrate
         | good judgement and mostly it does not.
         | 
         | Personally I wish people would just forget about Clean Code.
         | You're better off avoiding it or treating it as an example of
         | things not to do.
        
           | CSMastermind wrote:
           | I watched some talks he gave 15 years ago and what struck me
           | was that he would use analogies to things like physics that
           | were just objectively incorrect. He was confidently talking
           | about a subject he clearly didn't understand at even an
           | undergraduate level.
           | 
           | Then for the rest of the talk he would speak just as
           | confidently about coding. Why would I believe anything he has
           | to say when his confidence is clearly not correlated to how
           | well he understand the material?
        
           | wglb wrote:
           | > I haven't seen a lot of evidence that Martin really has the
           | coding chops to speak as authoritatively as he does
           | 
           | From what I can deduce, his major coding work was long in the
           | past, and maybe in C++.
        
         | jbm wrote:
         | The Uncle Bob thing is something I'm experiencing right now.
         | 
         | I hired a friend who was a huge Uncle Bob mark, and he kept
         | trying to flex his knowledge during interviews with other
         | people in the company. I didn't really think much of it and
         | told the other interviewer that it was just his personal quirk
         | and not to worry much.
         | 
         | I had him work with some junior devs on a project while I took
         | care of something more urgent. After finishing it, I went over
         | to take a look at how it was going on his end. I was horrified
         | at the unnecessary use of indirection; 4 or 5 levels in order
         | to do something simple (like a database call). Worse, he had
         | juniors build entire classes as an interface with a database
         | class that was "wrong".
         | 
         | No practical work was done, and I've spent the past 4 weeks
         | building the real project, while tossing out the unnecessary
         | junk.
         | 
         | I liked Clean Code when I read it, but I always assumed a lot
         | of it was meant for a specific language at a specific time. If
         | you are using it verbatim for a Python project in 2025, why?
        
           | randomNumber7 wrote:
           | I don't see how it is uncle Bob's fault that your friend
           | misunderstood his book.
        
             | jbm wrote:
             | Judging from this thread, it seems like a lot of people
             | have similar issues with UB's work.
        
               | kreetx wrote:
               | It might just be that the divide of a getting-things-done
               | developer and a bloat developer isn't really caused by
               | Uncle Bob but merely correlates with it. I.e, good
               | developers also agree with Uncle Bob, though apparently
               | with a different interpretation of what he said.
        
               | randomNumber7 wrote:
               | Smart people read a book and critically think about it.
               | The others think it was written by a superhuman and turn
               | everything into religious beliefs.
        
               | kreetx wrote:
               | I meant that the book is interpreted differently by
               | different people. (That no-one takes it as religion, but
               | that some read it as recommending to "create a mountain
               | of unnecessary abstractions", and others read it that
               | "add necessary abstractions".)
        
             | Cthulhu_ wrote:
             | Not so much UB himself, but a developer being told a book
             | or person is authoritative / has the final word on a
             | subject isn't healthy.
        
         | motorest wrote:
         | > It's striking to me how out of touch Martin seems to be with
         | the realities of software engineering in this transcript.
         | Stylistic refactors that induce performance regressions,
         | extremely long and tortured method names for three-line
         | methods, near-total animus towards comments ... regardless of
         | who is right/wrong about what, those takes seem like sophomoric
         | extremism at its worst, not reasoned pragmatism that can be
         | applied to software development in the large.
         | 
         | I think you're talking out of ignorance. Let's take a moment to
         | actually think about the arguments that Uncle Bob makes in his
         | Clean Code book.
         | 
         | He argues in favor of optimizing your code for clarity and
         | readability. The main goal of code is to help a programmer
         | understand it and modify it easily and efficiently. What
         | machines do with it is of lower priority. Why? Because a
         | programmer's time is far more expensive than any infrastructure
         | cost.
         | 
         | How do you make code clear and easy to read? Uncle Bob offers
         | his advise. Have method names that tell you what they do, so
         | that programmers can easily reason about the code without
         | having to even check what the function does. Extract low-level
         | code to higher level methods so that a function call describes
         | what it does at the same level of detail. Comments is a self-
         | admission you failed to write readable code, and you can fix
         | your failure by refactoring code into self-descriptive member
         | functions.
         | 
         | Overall, it's an optimization problem where the single
         | objective is defined as readability. Consequently, it's obvious
         | that performance regressions are acceptable.
         | 
         | Do you actually have any complain about it? If you read what
         | you wrote, you'll notice you say nothing specific or concrete:
         | you only throw blanket ad hominems that sound very spiteful,
         | but are void of any substance.
         | 
         | What's the point of that?
         | 
         | > Maintainability/appropriate factoring are subjective
         | qualities that depend a lot on the project, the other
         | programmers on it, and the expectations around how software
         | engineering is done in that environment.
         | 
         | The problem with your blend of arguments is that guy's like you
         | are very keen on whining and criticizing others for the
         | opinions they express, but when lightly pressed on the subject
         | you show that you actually have nothing to offer in the way of
         | alternative or guideline or anything at all. Your argument
         | boils down to "you guys have a style which you follow
         | consistently, but I think I have a style as well and somehow I
         | believe my taste, which I can't even specify, should prevail".
         | It's fine tha you have opinions, but why are you criticizing
         | others for having them?
        
           | Mossy9 wrote:
           | > Comments is a self-admission you failed to write readable
           | code, and you can fix your failure by refactoring code into
           | self-descriptive member functions
           | 
           | This may be true for some cases, but I don't see a non-
           | contrived way for code to describe why it was written in the
           | way it does or why the feature is implemented the way it is.
           | If all comments are bad, then this kind of documentation
           | needs to be written somewhere else, where it will be
           | disconnected from the implementation and most probably
           | forgotten
        
             | motorest wrote:
             | > This may be true for some cases, but I don't see a non-
             | contrived way for code to describe why it was written in
             | the way it does or why the feature is implemented the way
             | it is.
             | 
             | I have to call bullshit on your argument. Either you aren't
             | even looking because you have the misfortune of only
             | looking at bad code written by incompetent developers, or
             | you do not even know what it looks like to be able to tell.
             | 
             | The core principles are quite simple, and are pervasive.
             | Take for example replacing comments with self-descriptive
             | names. Isn't this something obvious? I mean, a member
             | function called foobinator needs a combination of comments
             | and drilling down to the definition to be able to get a
             | clue on what it does. Do you need a comment to tell what a
             | member function called postOrderMessageToEventBroker does?
             | 
             | Another very basic example: predicates. Is it hard to
             | understand what a isMessageAnOrderRequest(message) does?
             | What about a message.type == "command" &&
             | type.ToUpperCase() == "request" && message.class ==
             | RequestClass.Order ? Which one is cleaner and easier to
             | read? You claim these examples are contrived, but in some
             | domains they are more than idiomatic. Take user-defined
             | type assertions. TypeScript even has specialized language
             | constructs to implement them in the form of user-defined
             | type guards. And yet you claim these examples are
             | contrived?
             | 
             | I'm starting to believe all these vocal critics who
             | criticize Uncle Bob or Eric Evans or any other author are
             | actually talking out of sheer ignorance about things they
             | know nothing about. They read some comment in some blog and
             | suddenly they think they are an authority on a subject they
             | know nothing about.
             | 
             | So much noise.
        
               | manmal wrote:
               | > Do you need a comment to tell what a member function
               | called postOrderMessageToEventBroker does?
               | 
               | Which event broker? Will I get a response via some
               | callback? What happens if the sending fails, is there a
               | retry mechanism? If yes, how many retries? What happens
               | when the retry count is exceeded? Will the order's ID be
               | set by this method? Is the method thread-safe? Which
               | errors can be thrown? ,,Don't call this before the event
               | broker has warmed up / connected". Etc etc
        
               | crackrook wrote:
               | > Do you need a comment to tell what a member function
               | called postOrderMessageToEventBroker does?
               | 
               | Obviously not and the comment you're replying to hasn't
               | asserted otherwise. They say, clearly, that comments
               | should explain the _why_, postOrderMessageToEventBroker
               | explains only the _what_ (which is reflected in the
               | verbiage of your question). Fortunately comments are
               | practically free and we're not limited to doing the
               | reader one-favor-per-statement, we can explain _both_ the
               | why with a comment (when it's not obvious) and the what
               | with clear function names.
        
               | Mossy9 wrote:
               | What I was refering to was the "why", not the "what" or
               | "how". This is not a good function name to my eye, but
               | YMMV: get-station-id-working-around-vendor-limitation-
               | that-forces-us-to-route-the-call-through-an-intermediary-
               | entity.
               | 
               | Instead, a comment can clearly and succintly tell me why
               | this implementation is seemingly more complex than it
               | needs to be, link to relevant documentations or issues
               | etc.
        
               | wglb wrote:
               | > I'm starting to believe all these vocal critics who
               | criticize Uncle Bob or Eric Evans or any other author are
               | actually talking out of sheer ignorance about things they
               | know nothing about.
               | 
               | I've been programming for 60 years in many different
               | fields. I was programming long before he was. It is
               | possible that I have written more code than he has in
               | more languages (36 at last count), so my criticism of his
               | are based on real-world experience.
        
           | sirwhinesalot wrote:
           | Code like Uncle Bob suggests is not easier to read and
           | understand, it is harder, IMO and that of many others. Since
           | the disagreement starts from this any further discussion is
           | impossible.
        
           | manmal wrote:
           | > The main goal of code is to help a programmer understand it
           | and modify it easily and efficiently. What machines do with
           | it is of lower priority.
           | 
           | This mentality sounds like a recipe for building leaky
           | abstractions over the inherent traits of the von Neumann
           | architecture, and, more recently, massive CPU parallelism.
           | Bringing with it data races, deadlocks, and poor performance.
           | A symptom of this mentality is also that modern software
           | isn't really faster than it should be, considering the
           | incredible performance gains in hardware.
           | 
           | > Comments is a self-admission you failed to write readable
           | code
           | 
           | I'm not buying this. It's mostly just not possible to
           | compress the behavior and contract of a function into its
           | name. If it were, then the compiler would auto-generate code
           | out of method names. You can use conventions and trigger
           | words to codify behavior (eg bubbleSort, makeSHA256), but
           | that only works for well-known concepts. At module
           | boundaries, I'm not interested in the module's inner
           | workings, but in its contract. And any sufficiently complex
           | module has a contract that is so complex that comments are
           | absolutely required.
        
             | motorest wrote:
             | > This mentality sounds like a recipe for building leaky
             | abstractions over the inherent traits of the von Neumann
             | architecture, and, more recently, massive CPU parallelism.
             | Bringing with it data races, deadlocks, and poor
             | performance.
             | 
             | No,not really. Just because you think about how to name
             | functions and what portions of your code should be easier
             | to read if the were extracted to a function,that doesn't
             | mean you are creating abstractions or creating problems.
             | 
             | The rest of your comments on von Neumann architecture etc
             | is pure nonsense. Just because your code is easy to read it
             | doesn't mean you're writing poetry that bears no
             | resemblance with how the code is executed. Think about what
             | you're saying: what is the point of making readable code?
             | Is it to look nice at the expense of bugs, or to help the
             | developer understand what the code does? If it's the
             | latter, what point do you think you're making?
        
           | zbentley wrote:
           | I'm not going to spend a long time responding to your
           | comment, since it seems accusatory and rude; if you modify it
           | to be more substantive I'll happily engage more.
           | 
           | The one specific response I have is: it's not that I
           | 
           | > say nothing specific or concrete: [I] only throw blanket ad
           | hominems that sound very spiteful
           | 
           | ...rather, it's that I'm criticizing Martin's approach to
           | _teaching_ rather than his approach to _programming_. I
           | expand on that criticism more in an adjacent comment, here:
           | https://news.ycombinator.com/item?id=43171470
        
           | spacechild1 wrote:
           | > What machines do with it is of lower priority. Why? Because
           | a programmer's time is far more expensive than any
           | infrastructure cost.
           | 
           | This assumes that code runs on corporate infrastructure. What
           | if it runs on an end user device? As a user I certainly care
           | about my phone's battery life. And we aren't even talking
           | about environmental concerns. Finally, there are quite a few
           | applications where speed actually matters.
           | 
           | > Comments is a self-admission you failed to write readable
           | code, and you can fix your failure by refactoring code into
           | self-descriptive member functions.
           | 
           | Self-explaining code is a noble goal, but in practice you
           | will always have at least some code that needs additional
           | comments, except for the most trivial applications. The world
           | is not binary.
        
           | AllegedAlec wrote:
           | > Comments is a self-admission you failed to write readable
           | code, and you can fix your failure by refactoring code into
           | self-descriptive member functions
           | 
           | # This is not the way I wanted to do this, but due to bug
           | #12345 in dependency [URL to github ticket] we're forced to
           | work around that.
           | 
           | # TODO FIXME when above is done.
           | 
           | Oh no, I so failed at making self-descriptive code. I'm
           | sorry, I totally should've named the method DoThisAndTHatButA
           | lsoIncludeAnUglyHackBecauseSomeDubfuckUpstreamShippedWithABug
           | .
        
         | lmm wrote:
         | > I worry that his approach allows a certain kind of programmer
         | to focus on like ... aesthetic, dogmatic uniformity (and the
         | associated unproductivity of making primarily aesthetically-
         | motivated, dogmatic changes rather than enhancements, bugfixes,
         | or things that other coders on a project agree improves
         | maintainability) instead of increasing their skills and
         | familiarity with their craft.
         | 
         | Funny, I find the opposite. In my experience people that are
         | willing to take a "dogmatic" position on code style are those
         | who are able to actually get on with implementing features and
         | bugfixes. It's the ones who think there's a time and place for
         | everything and you need to re-litigate the same debates on
         | every PR who tie themselves in knots getting nothing done.
         | 
         | Do I agree with absolutely everything Martin writes? In
         | principle, no. But I'd far rather work on a codebase and team
         | that agrees to follow his standards (or any similar set of
         | equally rigid standards, as long as they weren't insane) than
         | one that doesn't.
        
       | mkoubaa wrote:
       | I can just tell that John Ousterhout works with much better
       | developers on average than UB and that probably informs their
       | biases.
        
         | Jach wrote:
         | He also works with a lot more students, with student-sized
         | projects and problems and code lifetimes. He's used his book
         | for classes, I think it's on a level appropriate for a
         | freshman.
         | 
         | Both books are bad, but APOSD is my most disliked technical
         | book ever. CC is at least interesting as an exercise to see
         | that critics are way too uncharitable. Kernighan and Pike's
         | _The Practice of Programming_ is far better than either. And
         | https://antirez.com/news/124 is one of the few good discourses
         | on comments out there, something as a profession we care way
         | too much about when the cost of doing it "wrong" is typically
         | so low.
        
           | tikhonj wrote:
           | What's there to dislike so much in APOSD?
           | 
           | The book struck me as giving mostly reasonable advice, none
           | is which was overly prescriptive. None of the things I
           | disagreed with struck me as _egregious_.
        
             | Jach wrote:
             | Here's mostly from what I wrote down after reading it.
             | Indeed, the "reasonableness" is part of the problem.
             | 
             | What's agreeable is mostly only so because it's such a
             | straightforward platitude. "Things that are not important
             | should be hidden, and the more of them the better. But when
             | something is important, it must be exposed." Ok? Anyone
             | want to argue to the contrary? This is not teaching or
             | learning anything new or of value, it's not even inviting
             | argument like CC makes it easy to do. I was also hoping
             | that with the book being so short it would be concise, but
             | alas, it's full of this sort of stuff. The single page
             | summary of design principles at the end is similar. A few
             | of them you could quibble about, but arguments would likely
             | just be in fully understanding the meaning of the
             | terminology and what background contexts are assumed. Much
             | advice is dependent on context! Context is something not
             | really called out much in this book. As one example there
             | was only a very slight hint that the author is aware that
             | writing for the code reader means a reader from a
             | particular audience, often your co-workers, and that gives
             | you certain affordances you wouldn't have for say random
             | blogger.
             | 
             | Elsewhere, not in the book, the author once wrote "The
             | strong typing of object-oriented languages encourages
             | narrowly defined packages that are hard to reuse. Each
             | package requires objects of a specific type; if two
             | packages are to work together, conversion code must be
             | written to translate between the types required by the
             | packages." This is actually a nuanced point and is good to
             | discuss. The context of whether you have static types or
             | dynamic types or a half-baked OOP system or a full-baked
             | OOP system is very important context. But it seems a
             | completely absent point of consideration from his
             | "philosophy", even when you'd think it'd be appropriate to
             | go over in the final chapter where he highlights OOP as a
             | "trend".
             | 
             | A lot of the author's rants seem to be snipes at Java.
             | Fine, whatever, though Java has answers to the complaints.
             | (Especially modern Java.)
             | 
             | Lastly, and originally my first complaint because it's
             | about the very beginning of the book (including the cover
             | art), he's on shaky foundations with its definition of
             | simplicity/complexity by conflating it with the subjective
             | easy/hard. I was hoping for a post-Hickey (of
             | Clojure/"Simple Made Easy" talk fame for anyone unaware)
             | understanding that complexity is objective, but alas. It's
             | not like Hickey invented that understanding, but in current
             | year, I think it's quite questionable to disagree. So, the
             | book: "For the purposes of this book ... complexity is
             | anything related to the structure of a software system that
             | makes it hard to understand and modify the system." Sorry,
             | that's not a useful definition of complexity, and now the
             | whole book is harder to read/easier to misinterpret because
             | of the custom definition. Well, at least it's explicit that
             | it's custom.
        
               | WillAdams wrote:
               | What definition of complexity in the context of
               | discussing software development and architecture would
               | you put forward instead?
        
               | allemagne wrote:
               | He could have chosen a different word besides
               | "complexity" but I don't really think it would have
               | affected much. The subjective easy/hard is specifically
               | what Ousterhout is trying to talk about.
               | 
               | Ultimately the problem he is (and all of us are) facing
               | is that "good software design" can't really be measured
               | with the right linting ruleset or static analysis. So if
               | you're trying to break the concepts down each level,
               | while still maintaining a scope that should include all
               | software, that probably means it's impossible not to come
               | off as squishy and non-specific at several points. I
               | still think he strikes a really good balance in general
               | here.
               | 
               | I agree that there could be more discussion around
               | context and audience. Ousterhout says "if you write a
               | piece of code and it seems simple to you, but other
               | people think it is complex, then it is complex", but then
               | what can possibly be done if everyone on my team was
               | replaced with new hires who had next to no experience
               | writing code? Did the same codebase go from simple to
               | complex?
        
               | colonCapitalDee wrote:
               | If you dismiss all the parts of APOSD that you agree with
               | as straightforward and trivial, then obviously the only
               | parts left for consideration are the parts you disagree
               | with. APOSD is not an academic paper, it does not claim
               | to be wholly and truly original. You are presumably an
               | expert programmer, so it makes complete sense that much
               | of the content discussed in APOSD appears to be
               | "straightforward platitudes". To you, the content is
               | trivial and obvious. But to the new grad with one year of
               | work experience, the content is novel and informative.
               | Perhaps you should take your own advice and consider the
               | context.
        
           | WillAdams wrote:
           | While reading APoSD, one of my thoughts was that it walks up
           | to, but never gets to the point of advocating for Literate
           | Programming, and that resolving how the author feels about
           | that presentation would make for a better and clearer text.
           | 
           | Apparently, there is something of a tension at Stanford in
           | that freshmen are being taught to keep methods/functions
           | short, while the course on software design has as a pre-
           | requisite CS140 which in turn requires CS 107 or EE 108B and
           | CS107 requires CS106B, so it probably couldn't be taken until
           | almost halfway through a four-year degree (and there is a
           | note on the course page that preference will be given to
           | those graduating in the near term).
           | 
           | That said, there is value in laying out basic principles and
           | premises, _and_ the experiences which in turn support them.
           | Reading through your link, it seems to line up well with my
           | understanding of recommendations for comments in APoSD, which
           | makes one wonder how it could be made to work as a text for
           | an introductory course in some language which was
           | approachable by beginners.
        
       | sudobash1 wrote:
       | There is an important case for comments that neither of them
       | touched on. Sometimes you are dealing with bugs or
       | counterintuitive processes beyond your control.
       | 
       | For example, I am writing some driver software for a USB device
       | right now. It is so easy to get the device into a bad state, even
       | when staying within the documented protocol. Every time I
       | implement a workaround, or figure out exactly how the device
       | expects a message to appear, I put in a comment to document it.
       | Otherwise, when (inevitably) the code needs to have features
       | added, or refactoring, I will completely forget why I wrote it
       | that way.
       | 
       | The prime number example is a self-contained, deterministic
       | algorithm. While I did find it far easier to parse with comments,
       | I could still spend the time to understand it without them. In my
       | USB device driver, no amount of review without comments would
       | tell another person why I wrote the sequence of commands a
       | certain way, or what timings are important.
       | 
       | The only way around that would be with stupid method names like
       | `requestSerialNumberButDontCallThisAfterSettingDisplayData` or
       | `sendDisplayDataButDontCallTwiceWithin100Ms`.
        
         | mbo wrote:
         | While I am not a Uncle Bob-style "no comments"er I do love a
         | ridiculous method name. I pay very close attention to that
         | method and the context in which it is called because, well, it
         | must be doing something very weird to deserve a name length
         | like that.
        
           | tikhonj wrote:
           | There are a few Haskell functions with names like
           | reallyUnsafePtrEquality# or accursedUnutterablePerformIO, and
           | you _know_ something interesting is going on :P
        
           | hakunin wrote:
           | That's exactly why you should save that length only for a
           | method that's indeed doing something weird. If every method
           | is long, the codebase turns into noise. (IOW I agree)
        
             | ninetyninenine wrote:
             | This doesn't happen in reality. Your program does so many
             | things that practically speaking short names work for a lot
             | of functions in the program. It's like English. There are
             | big words and there are small words and usually to
             | communicate a combination of big and small words are used.
             | 
             | Nobody practically communicates with big words. A long
             | function name only pops up when needed.
        
               | hakunin wrote:
               | It happened in the article we're discussing, and seems to
               | be something Robert advocates for.
        
               | ninetyninenine wrote:
               | Happened in a contrived example.
        
             | Pxtl wrote:
             | I used to work this way, but I found that every non-trivial
             | method involves edge-cases and workarounds documenting them
             | the method name destroyed readability.
        
               | hakunin wrote:
               | The only point I was making is that short name signals
               | that nothing unusual is going on, and long name signals
               | that you have to pay extra attention. I never suggest to
               | replace a comment with a long name. Here's my 4 reasons
               | to leave a comment: https://max.engineer/reasons-to-
               | leave-comment Comments are crucial for "why", and
               | additional context. Name shouldn't go beyond "what". More
               | on that here: https://max.engineer/maintainable-code
               | (Check the "What" section that focuses on naming).
        
         | zbentley wrote:
         | > The only way around that would be with stupid method names
         | 
         | Yep. Method names make terrible comments. No spaces, hard to
         | visually parse, and that's before acronyms and ambiguity enter
         | the conversation.
         | 
         | As the person who often writes borderline-essay-length comment
         | blocks explaining particularly spooky behaviors or things to
         | keep in mind when dealing with a piece of
         | counterintuitive/sensitive/scary code, my reason for mega-
         | commenting is even simpler: all the stuff I put in comments
         | should _absolutely_ instead live in adjacent documentation (or
         | ADRs, troubleshooting logs, runbooks, etc). When I put it in
         | those places, people do not read it, and then they do the wrong
         | things with the code. When I put it in comments, they read it,
         | as evidenced by the rate of  "that bug caused by updating the
         | scary code in the wrong way happened again"-type events
         | dropping to zero. It's easier to fix comment blocks than it is
         | to fix engineers.
        
           | rswail wrote:
           | > Yep. Method names make terrible comments. No spaces, hard
           | to visually parse, and that's before acronyms and ambiguity
           | enter the conversation.
           | 
           | Which is why snake_case or kebab-case (if the language allows
           | it) is much better than PascalCase or camelCase.
           | 
           | Even worse when camelCase enters into JSON because people
           | want to automate the serde but are too lazy to make the
           | actual interface (the JSON Schema) easy to read and debug.
        
           | colddevil wrote:
           | Upvote for mentioning ADRs! ;)
           | 
           | I really like the approach and as other comments already
           | mentioned, this is a nice way to capture the "why" of
           | specific decisions that go beyond the "how" in the code.
           | 
           | Here is a good starting point for people not familiar with
           | ADRs: - https://cognitect.com/blog/2011/11/15/documenting-
           | architectu... - https://adr.github.io/
        
         | slotrans wrote:
         | > I will completely forget why I wrote it that way.
         | 
         | This is the main reason for comments. The code can never tell
         | you "why".
         | 
         | Code is inherently about "what" and "how". The "why" _must_ be
         | expressed in prose.
        
           | Cthulhu_ wrote:
           | And the described use case - USB stuff with very specific
           | exception - makes a strong case for literate programming,
           | that is, more prose than code.
        
             | lompad wrote:
             | Does everything have to be pushed into a structure-
             | prescribing set of rules?
             | 
             | Can't we just say "comments are useful here" without trying
             | to make it into a case for $methodology?
        
               | kragen wrote:
               | Literate programming isn't a structure-prescribing set of
               | rules or a methodology. It's just making the prose
               | primary and the code secondary.
        
           | ninetyninenine wrote:
           | Why not put the prose in the name of the function?
        
             | SAI_Peregrinus wrote:
             | Function names are limited. E.g. can't provide a circuit
             | diagram of what you're controlling in a function name. But
             | you can do that in a comment (either with ASCII art or an
             | image link).
        
               | ninetyninenine wrote:
               | Agreed. So why not stuff as much as possible into the
               | name before resorting to a comment? Prose looks ugly as a
               | name but the utility is not diminished.
        
               | SAI_Peregrinus wrote:
               | That embeds the "why" into your API. If it ever changes,
               | the function no longer serves as an abstraction over that
               | underlying reason & changing the function name breaks
               | your API.
               | 
               | That's not to say embed _nothing_ into the names. I 'm
               | quite fond of the "Long Names are Long" blog post[1]:
               | names need to clearly refer to what the named thing does,
               | and precise enough to exclude stuff it doesn't do. Names
               | can certainly get too short, e.g. the C "sprint fast"
               | function `sprintf` is probably too short to be easily
               | understood.
               | 
               | [1] https://journal.stuffwithstuff.com/2016/06/16/long-
               | names-are...
        
               | ricree wrote:
               | In addition to that, if the Why ever changes (maybe the
               | issue was in an external dependency that finally got
               | patched), you'd have to update the name or else leave it
               | incorrect. Mildly annoying if just in one codebase, but a
               | needlessly breaking change if that function is exported.
        
         | Mawr wrote:
         | Sounds like you should instead be making these invalid states
         | unrepresentable by encoding them in types and/or adding
         | assertions. Especially if you're exposing them as interfaces,
         | as your example function names would imply.
        
           | kragen wrote:
           | They're invalid states inside the USB device, not inside the
           | driver code. So nothing you do to the driver code can make
           | them unrepresentable. The best you can do is avoid frobbing
           | the device in the problematic ways.
        
           | marcosdumay wrote:
           | The GP is making those invalid states unreachable by writing
           | a device driver.
        
         | bch wrote:
         | > For example, I am writing some driver software for a USB
         | device right now. It is so easy to get the device into a bad
         | state, even when staying within the documented protocol. Every
         | time I implement a workaround, or figure out exactly how the
         | device expects a message to appear, I put in a comment to
         | document it. Otherwise, when (inevitably) the code needs to
         | have features added, or refactoring, I will completely forget
         | why I wrote it that way.
         | 
         | I believe in general there is a case for this (your case sounds
         | like a perfect candidate). The implementation of Dtrace is
         | another example[0] full of good description, including ASCII
         | diagrams (aside: a case for knowing a bit of Emacs (though I'm
         | sure vim has diagramming too, which I would know if I pulled
         | myself out of nvi long enough to find out)).
         | 
         | [0]
         | https://github.com/opendtrace/opendtrace/blob/master/lib/lib...
        
         | kragen wrote:
         | Have you thought about distilling your hard-earned information
         | about the device's behavior into a simulator for the device you
         | could test your code against?
        
         | ninetyninenine wrote:
         | I don't see anything wrong with those names. A bit hard to
         | parse but the name moves with the function call while a comment
         | does not.
         | 
         | It's annoying to look at but when you actually read the
         | function you know what it does. A more elegantly named function
         | is less annoying to read but less informative and doesn't
         | provide critical information.
         | 
         | The name just looks ugly. But it's like people have this ocd
         | need to make things elegant when elegance is actually
         | detrimental to the user. Can you actually give a legitimate
         | reason why a method name like that is stupid other then its
         | "hard to parse". Like another user said... use snake case if
         | you want to make it easier.
        
         | klysm wrote:
         | Encoding temporal dependencies (or exclusions) between methods
         | is hard. You can get partially there by using something like a
         | typestate pattern (common in rust).
        
       | marcusbuffett wrote:
       | I strongly recommend "A Philosophy of Software Design". It
       | basically boils down to measuring the quality of an abstraction
       | by the ratio of the complexity it contains vs the complexity of
       | the interface. Or at least, that's the rule of thumb I came away
       | with, and it's incredible how far that heuristic takes you. I'm
       | constantly thinking about my software design in these terms now,
       | and it's hugely helpful.
       | 
       | I didn't feel like my code became better or easier to maintain,
       | after reading other programming advice books, including "Clean
       | Code".
       | 
       | A distant second recommendation is Programming Pearls, which had
       | some gems in it.
        
         | narnarpapadaddy wrote:
         | Implicitly, IIRC, the optimal ratio is 5-20:1. Your interface
         | must cover 5-20 cases for it have value. Any fewer, the
         | additional abstraction is unneeded complexity. Any more, and
         | your abstraction is likely too broad to be
         | useful/understandable. The example he gives specifically was
         | considering the number of subclasses in a hierarchy.
         | 
         | It's like a secret unlock code for domain modeling. Or deciding
         | how long functions should be (5-20 lines, with exceptions).
         | 
         | I agree, hugely usual principle.
        
           | abhis3798 wrote:
           | This is a good rule of thumb, but what would be a good
           | response to have interfaces because, "what if a new scenario
           | comes up in the future"?
        
             | lmm wrote:
             | "We'll extract interfaces as and when we need them - and
             | when we know what the requirements are we'll be more able
             | to design interfaces that fit them. Extracting them now is
             | premature, unless we really don't have any other feature
             | work to be doing?"
        
             | Copenjin wrote:
             | The scenario NEVER comes up in the future as it was
             | originally expected. You'll end up having to remove and
             | refactor a lot of code. Abstractions are useful only used
             | sparingly and when they don't account for handling
             | something that doesn't even exist yet.
        
             | kragen wrote:
             | If you own the code base, refactor. It's true that, if
             | you're offering a stable interface to users whose code you
             | can't edit, you need to plan carefully for backward
             | compatibility.
        
             | narnarpapadaddy wrote:
             | When doing the initial design start in the middle of the
             | complexity to abstraction budget. If you have 100 "units of
             | complexity" (lines of code, conditions, states, classes,
             | use cases, whatever) try to find 10 subdivisions of 10
             | units each. Rarely, you'll have a one-off. Sometimes,
             | you'll end up with more than 20 in a group. Mostly, you
             | should have 5-20 groups of 5-20 units.
             | 
             | If you start there, you have room for your abstraction to
             | bend before it becomes too brittle and you need to
             | refactor.
             | 
             | Almost never is an interface worth it for 1 implementation,
             | sometimes for 3, often for 5-20, sometimes for >20.
             | 
             | The trick is recognizing both a "unit of complexity" and
             | how many "units" a given abstraction covers. And, of
             | course, different units might be in tension and you have to
             | make a judgement call. It's not a silver bullet. Just a
             | useful (for me at least) framing for thinking about how to
             | manage complexity.
        
           | kragen wrote:
           | Maybe some examples would clarify your intent, because all
           | the candidate interpretations I can think of are absurd.
           | 
           | The sin() function in the C standard library covers 264
           | cases, because it takes one argument which is, on most
           | platforms, 64 bits. Are you suggesting that it should be
           | separated into 260 separate functions?
           | 
           | If you're saying you should pass in boolean and enum
           | parameters to tell a subroutine or class which of your 5-20
           | use cases the caller needs? I couldn't disagree more. Make
           | them separate subroutines or classes.
           | 
           | If you have 5-20 lines of code in a subroutine, but no
           | conditionals or possibly-zero-iteration loops, those lines of
           | code are all the same _case_. The subroutine doesn 't run
           | some of them in some cases and others in other cases.
        
             | narnarpapadaddy wrote:
             | Think of it more like a "complexity distribution."
             | 
             | Rarely, a function with a single line or an interface with
             | a single element or a class hierarchy with a single parent
             | and child is useful. Mostly, that abstraction is overhead.
             | 
             | Often, a function with 5-20 lines or an interface 5-20
             | members or a class hierarchy with 5-20 children is a useful
             | abstraction. That's the sweet spot between too broad
             | (function "doStuff") and too narrow (function
             | "callMomOnTheLandLine").
             | 
             | Sometimes, any of the above with the >20:1 complexity ratio
             | are useful.
             | 
             | It's not a hard and fast rule. If your complexity ratio
             | falls outside that range, think twice about your
             | abstraction.
        
               | narnarpapadaddy wrote:
               | And with respect to function behavior, I'd view it
               | through the lens of cyclomatic complexity.
               | 
               | Do I need 5-20 non-trivial test cases to cover the range
               | of inputs this function accepts?
               | 
               | If yes, function is probably about the right level of
               | behavioral complexity to add value and not overhead.
               | 
               | If I need only 1 test or if I need 200 tests it's
               | probably doing too much or too little.
        
               | kragen wrote:
               | That's not what cyclomatic complexity is, and if you
               | think 5-20 test cases is enough for sin(), open(), or
               | Lisp EVAL, you need your head examined.
        
               | narnarpapadaddy wrote:
               | You're right, I suggested two different dimensions of
               | complexity there as a lens into how much complexity a
               | function contains. But I think the principle holds for
               | either dimension.
               | 
               | I don't think you need only 20 test cases for open().
               | Sometimes, more than 20 is valid because you're saving
               | across some other dimension of complexity. That happens
               | and I don't dispute it.
               | 
               | But the fact that you need >20 raises the question: is
               | open() a good API?
               | 
               | I'm not making any particular judgment about open(), but
               | what constitutes a good file API is hotly contested. So,
               | for me, that example is validation of the principle:
               | here's an API that's behaviorally complex and disputed.
               | That's exactly what I'm suggesting would happen.
               | 
               | Does that help clarify?
        
               | kragen wrote:
               | Yes, open() is a good API. I can't believe you're asking
               | that question! It's close to the Platonic ideal of a good
               | API; not that it couldn't have been designed better, but
               | almost no interface in the software world comes close to
               | providing as much functionality with as little interface
               | complexity, or serving so many different callers or so
               | many different callees. Maybe TCP/IP, HTTP, JSON, and SQL
               | compete along some of these axes, but not much else.
               | 
               | No, 20 test cases is not enough for open(). It's not even
               | close. There are 36 _error cases_ for open() listed in
               | the Linux man page for it.
               | 
               | What constitutes a good file API is not hotly contested.
               | It was hotly contested 50 years ago; for example, the
               | FCB-based record I/O in CP/M and MS-DOS 1.0, TOPS-20's
               | JFN-based interface, and OS/370's various access methods
               | for datasets were all quite different from open() and
               | from each other. Since about 35 years ago, every new
               | system just copies the Unix API with minor variations.
               | Sometimes they don't use bitwise flags, for example, or
               | their open() reports errors via additional return values
               | or exceptions instead of an invalid file descriptor.
               | Sometimes they have opaque file descriptor objects
               | instead of using integers. Sometimes the filename syntax
               | permits drive letters, stream identifiers, or variables.
               | But nothing looks like the I/O API of Guardian, CP/M,
               | Multics, or VAX/VMS RMS, and for good reason.
        
             | tremon wrote:
             | That function covers 264 inputs, not cases. It handles only
             | one case: converting an angular value to (half of) a
             | cartesian coordinate.
        
               | kragen wrote:
               | Sounds like you haven't ever tried to implement it. But
               | if the "case" you're thinking of is the "case"
               | narnarpapadaddy was referring to, that takes us to their
               | clause, "Any fewer [cases], the additional abstraction is
               | unneeded complexity." This is obviously absurd when we're
               | talking about the sin() function. Therefore, that can't
               | possibly have been their intended meaning.
        
               | tremon wrote:
               | The alternative and more charitable interpretation, of
               | course, is that a single function like sin() is not what
               | said GP meant when using the word "interface". But hey,
               | don't let me interrupt your tilting at straw men, you're
               | doing a great job.
        
       | getnormality wrote:
       | Uncle Bob's insistence that functions should be 2-4 lines long is
       | baffling to me. I don't understand how he can be taken seriously.
       | Is there a single application in the entire world with
       | substantial functionality that conforms to this rule?
        
         | Scubabear68 wrote:
         | There are. A lot of Java code bases look like this.
         | 
         | It is all as bad as you imagine. Functionality is spread out
         | all of the place so it is very difficult to reason about how it
         | all hangs together.
        
           | nyarlathotep_ wrote:
           | It's always fun stepping through 412 stack frames that are
           | all 2-line long methods to figure out where the thing you're
           | interested in actually happened.
        
           | MobiusHorizons wrote:
           | I once fully spelunked such a Java call stack to convert some
           | code to golang. It was amazing, there were like 5 layers of
           | indirection over some code that actually did what I want, but
           | I had to fully trace it keeping arguments from the full call
           | stack in mind to figure this out, because several of the
           | layers of indirection had the potential of doing
           | substantially more work with much more complex dependency
           | graphs. I ended up with a single go file with two functions
           | (one that reproduced the actually interesting Java code and
           | one that called it the way it would have been called across
           | all the layers of indirection. It was less than 100 lines and
           | _much_ easier to understand.
        
           | monksy wrote:
           | Add in Go and C++ code bases to that as well.
        
         | PlunderBunny wrote:
         | I've seen this in what I call 'lasagna code' - multiple thin
         | layers that seem to do nothing (or almost nothing) but each one
         | is an implementation of some abstruse interface that exists in
         | the mind of the original developer.
         | 
         | Eventually, your code has to _do_ something. Get that thing in
         | one place where you can look at it in its whole.
        
         | WalterBright wrote:
         | Too often I see functions that are shells that reshuffle the
         | arguments and pass them to another function, which also
         | reshuffles the arguments and forwards them to another, and on
         | and on. One was 11 layers deep.
        
           | Copenjin wrote:
           | And a lot of people doesn't understand how dangerous
           | shuffling parameters is, especially in languages that do not
           | have named parameters...
        
             | Pxtl wrote:
             | Powershell is an _awful_ language but it has made me fall
             | in love with named parameters. Name all the things.
        
           | mrkeen wrote:
           | If you have a 2-4 line function and you spot this, you can
           | trivially remove it.
        
           | js8 wrote:
           | I have seen such code too - with just S,K and I combinators.
           | It wasn't readable.
        
         | monksy wrote:
         | This is something that's easier to read than it is to
         | understand. A lot of languages force you to do quite a lot in a
         | function and becoming blind to bloat is way to easy to do.
         | (C++/Go/Java/etc yep).
         | 
         | He did an example in the article of:
         | 
         | void concurrentOperation() { lock() criticalSection(); unlock()
         | }
         | 
         | So if you subsitute criticalSection with a lot of operations,
         | such as open file, read lines, find something, close file. I
         | think you have a better representation of an over bloated
         | function.
         | 
         | Scala has the langauge support to show what this could look
         | like.
         | 
         | What you're doing in that method is starting a critical
         | section, doing something, and then ending a critical section.
         | It's a good suggestion to break that with:
         | 
         | def criticalSection(f: () => Unit) { lock() f() unlock() }
         | 
         | How you have a single method that does one thing and is easy to
         | understand. Also it's reusable.
         | 
         | The original code would be used as:
         | 
         | criticalSection { _ => doSomething() }
         | 
         | That replacement is now longer dependent on locking. Locking is
         | layered in.
        
         | dionian wrote:
         | Like with a lot of his approach, its great for teaching people
         | better coding skills in an educational setting, but doesn't
         | make as much sense in the real world.
        
         | lmm wrote:
         | Yes, I've worked on a couple of codebases like that. It's
         | glorious, you break everything down little by little and every
         | step makes sense and can be tested individually. Best jobs I've
         | had.
        
           | MrJohz wrote:
           | But are those steps actually doing anything that can be
           | tested? My experience with these sorts of codebases was
           | always that most of the functions aren't doing much other
           | than calling other functions, and therefore testing those
           | functions ends up either with testing exactly the same
           | behaviour in several places, or mocking so heavily as to make
           | the test pointless.
           | 
           | Or worse, I've seen people break functions apart in such a
           | way that you now need to maintain some sort of class-level
           | state between the function calls in order to get the correct
           | behaviour. This is almost impossible to meaningfully test
           | because of the complex possible states and orders between
           | those states - you might correctly test individual cases, but
           | you'll never cover all possible behaviours with that sort of
           | system.
        
           | CyberDildonics wrote:
           | These large compound statements look nice if they are
           | perfect, but when you make giant expressions without
           | intermediate variables, it is much more difficult to test.
           | 
           | When you have small expressions that have incremental results
           | stored in variables, you can see the result in a debugger so
           | you can see each stage.
        
         | ninetyninenine wrote:
         | Yes. This works but only if the functions are pure and using
         | pure function composition.
         | 
         | Uncle bob doesn't mention this.
         | createspecialString(y) =            Capitalizefirstletter .
         | MakealllowerCase .            AddNumberSuffix .
         | removeLetterA .            removeLetterB .
         | ConcatwithWord(x)             CapitalizeFirstLetter(a) =
         | a[0].upper() + a[1:]        MakeAllLowercase(a) = map(a, (t) =>
         | t.lower())        Addnumbersuffix(a) a + 3.toString()
         | RemoveLetterA(t) = filter(t, (s) => s.lower() == "a")
         | RemoveLetterB(t) = filter(t, (s) => s.lower() == "b")
         | ConcatenateWithWord(x) = (y) => y + x
         | 
         | There see? It's mostly doable in pure functional composition
         | where the dot represents function composition. I program like
         | this all the time. No way anyone can pull this off while
         | mutating state and instantiating objects.                  F .
         | P = (x) => F(P(x))
         | 
         | Forgive some inconsistent formatting and naming im typing this
         | on my phone.
         | 
         | People who complain about this style tend to be unfamiliar with
         | it. If you had knowledge about procedural coding styles and a
         | function composition approach like this then usually this style
         | is easier as the high level function literally reads like
         | English. You don't need to even look at the definitions you
         | already know what this complicated string formatting function
         | does.
         | 
         | No comments needed. And neither author tells you about this
         | super modular approach. They don't mention the critical thing
         | in that this style requires functions to be pure.
         | 
         | Thus to get most of your code following this extremely modular
         | and readable approach... much of your code must be minimizing
         | IO and state changes and segregating it away as much as
         | possible.
         | 
         | The Haskell type system, the IO monad is pushing programmers in
         | this direction.
         | 
         | Again neither author talks about this.
        
           | LudwigNagasena wrote:
           | `createspecialString` is seven lines long though.
        
             | ninetyninenine wrote:
             | Then split it. All pure functions are easily decomposed
             | into the most primitive units so even the most dogmatic ass
             | hole can't talk shit.                  createSpecialString
             | = createFormattedString . createNewString
             | createFormattedString =             Capitalizefirstletter .
             | MakealllowerCase .            AddNumberSuffix .
             | createNewString(y) =             removeLetterA .
             | removeLetterB .            ConcatwithWord(x)
             | 
             | Or put it all on one line.
             | createspecialString(y) = Capitalizefirstletter .
             | MakealllowerCase . AddNumberSuffix . removeLetterA .
             | removeLetterB . ConcatwithWord(x)
             | 
             | The amount of lines becomes off topic once you get into
             | this style. It's a completely orthoganol concept as it's
             | completely irrelevant to readability and modularity.
             | 
             | Lines doesn't makes sense for pure non imperative
             | functions. Lines ONLY make sense for imperative functions
             | because each line represents an instruction.
        
           | mplanchard wrote:
           | Based on his blog, Martin has been getting into Clojure in
           | recent years. I was kind of hoping that the experience with a
           | functional lisp would shift some of opinions that he
           | previously stood by in Clean Code, but based on this
           | discussion, it doesn't seem like it.
        
         | CyberDildonics wrote:
         | John Carmack would disagree with Uncle Bob and John Carmack
         | actually programs.
         | 
         | My own experience is that with an IDE that can collapse a new
         | scope in the middle of a function, you can make large functions
         | that accomplish a lot and are very clear by writing a comment
         | and starting a new scope.
         | 
         | If something is going to be called multiple times a new
         | function makes sense, but this idea that anything that can
         | eventually return a single value needs to be it's own function
         | is a giant pain that creates more problems than it solves.
         | 
         | Just makeing a new scope in the middle of the functions lets
         | you use all the variables in the outer scope, do
         | transformations without introducing new variables and
         | ultimately "return" a new variable to the outer scope.
         | 
         | I've never understood why polluting namespaces with dozens or
         | hundreds of names (most of which may not be very descriptive
         | since naming a hundred small things is already going to be
         | confusing) is seen as a good idea. You look at a list and you
         | have no idea what is important and what was being shoved in
         | there to satisfy some do nothing public speaker's arbitrary
         | rules.
        
           | layer8 wrote:
           | The problem with collapsing is that you need to know a priori
           | which sub-scopes are independent and hence collapsible and
           | which aren't. Meaning, you have to analyze the unfamiliar
           | code first in order to know which sub-scopes you might want
           | to collapse. And, given an already-collapsed sub-scope, due
           | to it being collapsed you can't see if it reads or mutates
           | some local variable. The benefit of extracted functions is
           | that you _know_ that they are independent of the
           | implementation details of the caller (i.e. can't possibly
           | depend on or modify local variables of the caller other the
           | ones passed as arguments).
           | 
           | Too many arguments can become a problem. Nested functions can
           | help here, because they allow you to move their
           | implementation "out of the way" while still having access to
           | shared variables. And sometimes a collection of parameters
           | can sensibly become its own class.
           | 
           | IDE affordances are fine, but I'm opposed to _requiring_
           | reliance on them for reading and understanding code, as
           | opposed to writing.
        
             | CyberDildonics wrote:
             | _you need to know a priori which sub-scopes are independent
             | and hence collapsible and which aren't._
             | 
             | What does independent mean? I would just collapse them all
             | because they were meant to be collapsed in the first place.
             | 
             |  _you have to analyze the unfamiliar code first in order to
             | know which sub-scopes you might want to collapse_
             | 
             | Unfamiliar? I wasn't refactoring and collapsed them all.
             | 
             |  _The benefit of extracted functions is that you know that
             | they are independent of the implementation details of the
             | caller (i.e. can't possibly depend on or modify local
             | variables of the caller other the ones passed as
             | arguments)._
             | 
             | That's true to an extent, but this is more of a way to make
             | monolithic functions simple, which then makes the program
             | simpler over all because you can avoid lots of tiny little
             | functions. What you can end up with is programs that do non
             | trivial things but don't have tons of functions confusing
             | the issue.
             | 
             | Pragmatically this isn't really a problem. The whole "it
             | isn't exactly a 1:1 replacement" isn't the point. You can
             | still put in comments and const references if you really
             | want to.
             | 
             |  _IDE affordances are fine, but I'm opposed to requiring
             | reliance on them for reading and understanding code, as
             | opposed to writing._
             | 
             | Why would it be required? The alternative is that you still
             | have these commented sections with their own scope but they
             | aren't collapsed. You can always work on it without the IDE
             | and when you go back to the IDE it still works.
             | 
             | The reality of it is that you can see a broad overview of a
             | function then see details one section at a time and you
             | don't even have to go skipping around to other parts of the
             | file or other files to do it.
        
         | wglb wrote:
         | It is a bit weird.
         | 
         | However, a friend of mine was a professional Smalltalk
         | programmer. He claims that his median line count of methods,
         | over his 17 year career, was 4.
         | 
         | It is harder to do in other languages--it seems that C would be
         | on the order of 10.
         | 
         | Clearly it is a rule that can lead to complexity of too many
         | methods, compromising whatever gain smaller methods give you.
        
           | igouy wrote:
           | > median line count of methods
           | 
           | Auto-generate getters and setters for every instance variable
           | and that will drag the average down. (Maybe a lot of those
           | getters and setters should not have existed.)
        
         | igouy wrote:
         | fwiw Lines-of-Code / Method (Digitalk V/286 image, 1989) = 7
         | 
         | https://dl.acm.org/doi/10.1145/74878.74904
        
       | emtel wrote:
       | Related: https://news.ycombinator.com/item?id=27276706
        
       | namuol wrote:
       | I've come full-circle back to my junior engineer attitude with
       | respect to coding "best practices": Avoid anything resembling
       | dogma.
        
       | ctrlp wrote:
       | I've enjoyed both books but Uncle Bob is something you grow out
       | of. He was a bit of a cult figure at the time. Trying to actually
       | follow the guidelines in Clean Code taught me a lot about "over-
       | decomposition" and, ultimately, how _not_ to write code. It
       | reminds me it 's possible to take aesthetics so far the results
       | become ugly. Fussing over a proliferation of small functions that
       | do only one thing is a kind of madness. Each individual function
       | eventually does zero things. You are left sifting through the
       | ashes of your program wondering "Where did I go wrong?"
       | 
       | On the meta level, these exchanges, while mildly interesting,
       | have the vibe of debating how many angels can dance on the head
       | of a pin. I'm reminded of the old saying: "Writing about music is
       | like dancing about architecture." If you want to write good code,
       | read good code. Develop a taste that makes sense to you. I don't
       | think I'll ever read a book about code composition again.
        
         | Willingham wrote:
         | > If you want to write good code, read good code.
         | 
         | As a junior in the field working at a small company, I often
         | rely on this community for guidance, and this seems the most
         | sound advice on this thread.
        
           | acmj wrote:
           | You need to know what is good code. Opinions may vary a lot
           | between programmers, even senior ones. The _Clean Code_ cult
           | would tell you to find good code there but that is the most
           | poisonous programming book I have read.
        
             | ctrlp wrote:
             | there are lots of very robust programs in various languages
             | to learn from. It would be hard to know in isolation but by
             | contrast it is easier to learn what good code looks like.
             | Some code will flow and be easy to read. Other code will be
             | obtuse. Start with simpler projects that don't involve a
             | lot of low-level calls. Work up to more complex
             | implementations. There was never a better time to read code
             | than now with an LLM as a tutor. If you use one of the AI-
             | integrated editors or a code packer you can provide a lot
             | of context to the LLM. Ask the LLM for important modules
             | and work your way through them. Ask it for alternative
             | implementations of a function or translated into a
             | different language. Set up an program in a running
             | environment and walk through using a debugger. Look at the
             | way the code is organized in files and modules. You will
             | inevitably encounter cruft and "bad code". Sometimes there
             | are good reasons for that too. If you prefer books, the
             | Architectures of Open Source Applications (AOSA) books are
             | interesting, but there really isn't a way to avoid pulling
             | down a repo and reading the code. Soon, you'll develop your
             | own taste for what makes sense to you and be able to think
             | independently about the choices the developer made.
             | 
             | It is a bit sad but I think with the advent of LLMs some of
             | the stylistic quirks of programmers past will become a bit
             | anachronistic. Still, they will present opportunities for
             | code archeology.
        
             | namuol wrote:
             | Forget about the code itself and focus on the results.
             | 
             | What I mean by that: Good code is code that has proven
             | itself by surviving quietly in a long-living project that
             | has changed a lot over many cycles of new engineers
             | (experienced or otherwise) being onboarded. The less you
             | hear people complain about it but the more you find people
             | using or relying on it in some way, the better the code. If
             | people are loud about how much they like it, it's either
             | new, or it's something they've convinced themselves to like
             | but know in their hearts is bad. It's the stuff that just
             | works that's good - it's so good people don't even notice
             | it.
        
               | tcfhgj wrote:
               | Not really, long-living projects don't adapt their
               | complete code base with gained experience, much like the
               | Linux Kernel probably will never be rewritten in Rust,
               | C++ projects never transformed to C++14+, etc.
        
               | regularfry wrote:
               | The interesting thing to look for here is the parts of
               | the codebase that _don 't need_ to adapt with gained
               | experience. That's the key. If people aren't changing it,
               | they haven't needed to, and that's a useful signal.
               | 
               | Conversely, looking for the parts of a codebase with the
               | highest churn will tell you _immediately_ what all the
               | devs on that codebase will complain about, if you ask
               | them. This has worked for me extremely well across a
               | number of projects.
        
               | yxhuvud wrote:
               | It can also mean "We have not changed this because we
               | don't dare to do that, or it is too much work and we just
               | have to live with the bad decisions made 25 years ago".
               | And that is the last code you want to copy.
        
               | namuol wrote:
               | It's interesting that we just assume a newer language
               | produces "better code"
        
               | yxhuvud wrote:
               | No, because then you end up reading old C-code that are
               | IFDEF mazes and think that is good code. No, to see good
               | code you usually have to look at what experienced people
               | write when they get to greenfield something new.
        
               | namuol wrote:
               | So you think code that is ugly is bad code? Or is it that
               | it uses janky/outdated features? What makes it good if
               | not its lifetime value?
               | 
               | Surely you don't just presume the quality of code based
               | on the person who wrote the code, right?
        
               | yxhuvud wrote:
               | What makes it good is the tradeoff between how well it
               | solves the problem compared to how easy it is to
               | maintain. And people learn how to write better code as
               | they get more experienced, but old projects are seldom
               | rewritten using the learnings - it is often just easier
               | to start over from scratch.
        
               | bluGill wrote:
               | You have to read a lot of different code. Everyone thinks
               | their code is good when they write it. Often old ugly
               | code has a beautiful design still hidden behind many many
               | requirements changes that didn't fit with the original
               | design. Other code looks nice and beautiful but it will
               | stand the test of requirement changes even worse than the
               | other.
        
               | wglb wrote:
               | > Forget about the code itself and focus on the results.
               | 
               | This reminds me of what Dijkstra said (paraphrasing): the
               | computation is the important thing, not the code.
        
           | rswail wrote:
           | Agreed.
           | 
           | Some other heuristics:
           | 
           | * Every if statement is a chance of a bug because the code
           | has two or more paths to follow. Keep the choice making at
           | the business/requirements level of the code, not hidden
           | inside lower level decomposition.
           | 
           | * A switch statement that is not exhaustive (ie covers all
           | possible values) is a change of a bug, especially if there is
           | no default case.
           | 
           | Modern languages with better type systems make the second
           | point less relevant because they require exhaustive pattern
           | matching.
        
             | tremon wrote:
             | _Every if statement is a chance of a bug because the code
             | has two or more paths to follow_
             | 
             | This is known as the cyclomatic complexity of a program:
             | https://en.wikipedia.org/wiki/Cyclomatic_complexity
             | 
             | A corollary to this is that it is also beneficial to
             | converge separate paths as quickly as possible (e.g. using
             | non-nullable types and default values) or converge them all
             | to the same place (e.g. nonlocal exception handling).
        
               | wglb wrote:
               | I often abbreviate that to "Psychosomatic Complexity"
               | because more complex code is likely to give the
               | programmer a headache.
        
         | golol wrote:
         | >Each individual function eventually does zero things.
         | 
         | Lambda calculus, basically :)
        
         | mplanchard wrote:
         | > You are left sifting through the ashes of your program
         | wondering "Where did I go wrong?"
         | 
         | Brilliantly phrased metaphor, thank you.
        
         | kraftman wrote:
         | it has been years since I read the book, but I'm surprised that
         | there's so much hatred for it here. From memory it seemed like
         | fairly harmless things like give things good names, try to make
         | the code readable, dont comment what the code does but why, use
         | consistent formatting, avoid duplication.
         | 
         | Other than people going overboard with empty classes and
         | inheritance Ive not really seen a problem of people breaking
         | down functions too far.
         | 
         | Which parts are important to grow out of?
        
           | InvisibleUp wrote:
           | There's a good overview of the faults of Clean Code at
           | https://qntm.org/clean.
        
       | WalterBright wrote:
       | One method of commenting that has paid off for me the most was
       | inserting links to:
       | 
       | 1. the online documentation of the function being called
       | 
       | 2. the instruction documentation for an instruction being
       | generated, inserting
       | 
       | 3. the issue that the code fixes
       | 
       | 4. the specification of what the function is trying to implement
       | 
       | Then I fixed my text editor to enable click on those links.
        
         | WalterBright wrote:
         | I also fixed the disassembler to also add a clickable link to
         | the instruction spec page for each instruction.
        
           | wglb wrote:
           | I did that back in the day (before we could click on
           | anything) about what the compiler was thinking as it
           | generated the code. That was fun.
        
       | vishnugupta wrote:
       | While on this topic, one book I really enjoyed is "Beautiful
       | Code"[1]. It is not preachy or prescriptive but a diverse set of
       | programmers showing the code they enjoyed writing.
       | 
       | [1] https://www.goodreads.com/book/show/405790.Beautiful_Code
        
       | hakunin wrote:
       | For anyone like me who at first skipped over this article because
       | it seems from the title that someone just compared two
       | approaches:
       | 
       | No, it's an actual debate between the actual John and Bob. Them
       | debating each other. It's an amazing read.
        
       | seanwilson wrote:
       | I find the lack of discussion of type systems really surprising
       | in these sorts of discussions and books. Effective use of type
       | systems is a killer factor for me for creating clean, safe,
       | readable and maintainable software designs.
       | 
       | When used correctly, strong static type checking make certain
       | kinds of bugs impossible, spare you from writing many kinds of
       | tedious tests that often get in the way of refactoring, serve as
       | documentation, and make refactoring/maintenance an order of
       | magnitude faster and safer. Even when a type checker isn't
       | available, avoiding dynamic behaviour is very often the safer way
       | to go so learning how to think in that way is still beneficial.
       | 
       | Most of these minor topics like how big a function should be,
       | what to name your variables, or even if you write tests
       | before/after coding... it's like trying to come up with general
       | rules on how to write essays, creating graphic designs, or how to
       | cook. "It depends" on the context and juggling different
       | priorities each time. It's the kind of thing you only learn
       | properly through practice
       | (https://en.wikipedia.org/wiki/Tacit_knowledge), so there's only
       | so much to gain in reading about it or discussing it after you've
       | defined the no-brainer things to always do and always avoid.
        
         | WillAdams wrote:
         | That was exactly the approach taken by Prof. Ousterhout in
         | setting up the class which lead to this book --- rather than
         | just having students turn in working code for a grade, the code
         | is reviewed with the student and the student then works to make
         | it better --- in turn, the 2nd edition of the book was informed
         | by the experience of teaching the class and the author actually
         | changed his position based on the experience gained.
        
           | seanwilson wrote:
           | Why is that convincing though? Students aren't experienced
           | coders, aren't working in large teams, and student
           | assignments aren't like long-term large commercial projects.
           | 
           | If you mean the additions here
           | https://web.stanford.edu/~ouster/cgi-bin/book.php, I read
           | these and it still sounds like general rules of thumb you'll
           | only really learn and understand by practicing a lot e.g. "In
           | my experience, the sweet spot is to implement new modules in
           | a somewhat general-purpose fashion" "Having good taste is an
           | important part of being a good software designer".
        
             | WillAdams wrote:
             | It's better credentials and experiential basis than most
             | other programming books.
             | 
             | Moreover, it is the students' inexperience which give this
             | text credence --- since it results in their making errors
             | and poor architectural/design choices it affords the chance
             | of correction.
             | 
             | I think it is remarkable that the author switched from
             | "modules should be specialized" to "modules should be
             | generalized" (rough paraphrasing, mailed my copy to Brazil
             | and waiting to buy a replacement).
             | 
             | If you know of other books which you merit recommendation
             | and which have a similar or better context for their
             | authorship and exposition, I would be glad to hear of them.
        
               | seanwilson wrote:
               | > It's better credentials and experiential basis than
               | most other programming books.
               | 
               | When considering coding advice, I just don't find
               | credentials or the results of a coding experiment matter
               | much, especially if it involves students. I run through
               | the scenarios in my head and pick the option that makes
               | sense given the context and competing priorities.
               | 
               | > I think it is remarkable that the author switched from
               | "modules should be specialized" to "modules should be
               | generalized" (rough paraphrasing, mailed my copy to
               | Brazil and waiting to buy a replacement).
               | 
               | The link I posted has a PDF with the content I think. I
               | guess I don't find the limited example involving a few
               | function signatures compelling (a student assignment to
               | write a basic text editor) or understand why I need to
               | pick whether to trend towards modules being specialized
               | or generalized... you treat it on a case-by-case basis,
               | pick the one that has the most benefits given the context
               | and be open to changing later when it makes sense?
               | Outside of a few rules, it's boring but "it depends"
               | really is the answer to most of these debates. Similar
               | with how long functions should be, writing comments and
               | how to name variables.
               | 
               | > If you know of other books which you merit
               | recommendation and which have a similar or better context
               | for their authorship and exposition, I would be glad to
               | hear of them.
               | 
               | Software Engineering at Google is probably relevant for
               | large projects: https://abseil.io/resources/swe-book
               | 
               | The rest probably best comes from practice, that's how I
               | learned most of what I know here. I'm didn't for example
               | become a fan of strong static types because of advice
               | based on credentials or experiments, but from experience
               | coding with and without types.
        
               | WillAdams wrote:
               | Thanks.
               | 
               | At a quick glance, that book seems to align well with
               | APoSD --- what aspects do you believe run counter to it?
        
               | seanwilson wrote:
               | The books aren't that similar I found. The Google one is
               | more about practical tips on the dev process of scaling
               | and maintaining software in teams, rather than focused on
               | code.
        
               | WillAdams wrote:
               | Okay.
               | 
               | What book that covers a similar range of topics as APoSD
               | would you suggest?
        
         | jghn wrote:
         | Because the pendulum of typing hadn't swung back to static
         | being in vogue when the Philosophy of Software Design came out.
         | At the time you had mostly the Scala & Haskell people standing
         | in a corner screaming until they (well, we as I was one of
         | them) were blue in the face about reducing "certain types of
         | bugs", and making impossible states impossible.
         | 
         | Since then, everyone and their brother is on the static typing
         | train. And from that lens you're right. It seems like an
         | omission. Give it another 10 years and people will probably
         | think the opposite.
        
         | pclmulqdq wrote:
         | Type systems and type-based coding patterns are very hip right
         | now, but they weren't 6 years ago. That is partly because the
         | type systems in the main languages in use 6 years ago were hack
         | jobs (to put it politely).
         | 
         | I do expect the pendulum to swing against type systems at some
         | point soon for the same reasons it swung against OOP: Too much
         | heavy lifting done by something that's hidden from the
         | programmer, encouraging people to be "too clever," etc. Like
         | OOP, algebraic types are a tool that have to be used well, and
         | the current users are people who really like type systems and
         | do use them well. It's only a matter of time before the tool
         | gets into the hands of the average programmer, and then we will
         | see how terribly a great type system can hurt you.
        
       | dionian wrote:
       | "That's a valid concern. However, it is tempered by the fact that
       | the functions are presented in the order they are called. Thus we
       | can expect that the reader has already seen the main loop and
       | understands that candidate increases by two each iteration."
       | 
       | I think this missed the point entirely. If i had to read the
       | entire code to understand the behavior of that method, then is it
       | really cleaner? Side-effects are evil
        
       | overgard wrote:
       | Bob's comments on... commenting.. are so bizarre that I can't
       | help but think that he just refuses to concede the point rather
       | than admit he might have been wrong about it. Like, the paranoia
       | around incorrect/stale comments is fairly absurd, I've been
       | coding for 20 years across many code bases, and I can't even
       | recall a time when I've been significantly mislead by a comment
       | which caused a significant waste of time. However, the amount of
       | time I've wasted on unclear code that has zero comments is
       | absolutely staggering. However, what really sealed the weirdness
       | to me was his argument that this was somehow a good comment:
       | X
       | 1111111111111111111111111                111112222233333444445555
       | 5666667777788888999990000011111222223333344444            3579135
       | 79135791357913579135791357913579135791357913579135791357913579135
       | 79            !!! !! !! !  !!  ! !! !  !  !!  ! !!  ! !  !   ! !!
       | !! !          3
       | |||-||-||-||-||-||-||-||-||-||-||-||-||-||-||-||-||-||-||-||-||-
       | 5 |||||||||||-||||-||||-||||-||||-||||-||||-||||-||||-||||-||||-
       | 7 |||||||||||||||||||||||-||||||-||||||-||||||-||||||-||||||-||||
       | ||-         11 ||||||||||||||||||||||||||||||||||||||||||||||||||
       | |||||||||-||||||||||-         13 ||||||||||||||||||||||||||||||||
       | ||||||||||||||||||||||||||||||||||||||||||         ...         11
       | 3||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
       | ||||||||||
       | 
       | That's verbatim, I'm not unfairly clipping context away from it.
       | Like, what the hell is that supposed to tell someone?! Wouldn't
       | it just be easier to drop a link to the algorithm, or briefly
       | explain the algorithm, or just give a name of the algorithm so
       | someone can look it up? Instead he just talks about taking a bike
       | ride to understand it and making a weird picture. He also has
       | bizarre arguments that if something can't be expressed in a
       | programming language, it's the fault of the programming language
       | (what?!) and that code is more understandable than English. I
       | really find it hard to believe that he thinks these are actually
       | good arguments, I just get the impression he does not want to
       | concede that he was wrong about this.
        
         | seabombs wrote:
         | Lol, this reminded me of those engravings we put on spacecraft.
         | Like, if we had to communicate the algorithm to an alien
         | civilization then sure, this might be the best way to do it!
         | 
         | https://en.wikipedia.org/wiki/Pioneer_plaque
        
           | lynguist wrote:
           | The juxtaposition of how the original comment starts, then
           | the appearance of the verbatim "good comment", then the
           | spacecraft engravings made me laugh tears.
           | 
           | Especially the buildup from how bizarre the understanding of
           | UB of comments is to actually seeing one "in the wild".
        
         | nvlled wrote:
         | > I'm not unfairly clipping context away from it
         | 
         | Yes you are, you didn't attach the surrounding code where this
         | comment was found. That comment would make a lot of more sense
         | even just with the function name.
        
           | badmintonbaseba wrote:
           | The code is there to explain the comment.
        
         | cjfd wrote:
         | Once you notice that the primes are in the top rows, it becomes
         | a pretty good comment.
        
           | xeyownt wrote:
           | Just learned that 9, 15, 21, ... are primes. Excellent
           | comment ^^.
        
             | froh wrote:
             | well, ackchyually, 'technically' the primes _are_ in there
             | in that top row
             | 
             | just not _only_ primes ^^
        
         | Terretta wrote:
         | > _so bizarre ... what the hell is that supposed to tell
         | someone?!_
         | 
         | I liked this bizarre comment. It was like seeing a physical
         | geometry proof for trig. Or like thinking about primes while
         | riding a bike for an hour.
         | 
         | In 10 - 15 seconds this comment offered a flash of appliable
         | intuition into primes I'd not appreciated before.
         | 
         | Granted, the bulk of that was first gathering that the top 3
         | rows of digits were a series turned sideways (printing them
         | rotated would have made that instant). Joys of plaintext.
         | 
         | But then the pattern popped, and the code, including the
         | optimization, made sense, but now from the "grok", with
         | MTOWTDI.
         | 
         | Neither their commentary nor their function names and comments,
         | caused the grok. I could "accept" the assertions, but to me
         | neither naming nor comments were _intuitively self-evident_ the
         | way the diagram was.
         | 
         | Both of them commented on having to dwell on what the code was
         | doing to consider refactoring. Once this flash happens, one no
         | longer needs reference code at all, it's just another property
         | of primes.
        
         | wglb wrote:
         | I'm pretty much in agreement with you on this, however I'm
         | always aware of the possibility of comments being bugs. If code
         | gets moved around, there is the very real possibility that the
         | comment is now attached to the wrong method or line of code.
         | 
         | I now comment on method or function basis, describing what the
         | method does. The how should be evident in the body itself.
         | 
         | He doesn't seem to often concede to being wrong.
        
       | jillesvangurp wrote:
       | They are both mostly right but the devil is in the details and to
       | try to not get too dogmatic about things. For example function
       | length is one of those things that you can obsess about and
       | debate endlessly.
       | 
       | What's the value of extracting a function that is used only once
       | or twice. It's probably very limited. It's debatable whether that
       | even should be a public function and whether you should encourage
       | more use. And then we can look at the function declaration as
       | well. Does it have a lot of parameters? Is there any complexity
       | to its implementation? Does it have tests? Are there going to be
       | lot of uses of the function? If the answer to all those questions
       | is no, you could probably inline it without losing much. But the
       | flip side is that you wouldn't gain much by doing so. A small
       | function that is used a lot is probably somewhat valuable.
       | 
       | And there's a third thing that needs to be considered: does a
       | function increase the API surface of your module. Having lots of
       | private functions makes your module hard to understand. Having
       | lots of public functions, makes the API less cohesive.
       | 
       | So, there's a grey area here. Languages like Kotlin give you a
       | additional options: make it a nested function, make it an
       | extension function, put it in a Companion object, etc. You can
       | put functions in functions and those can help readability. The
       | whole point of doing that is preventing usage outside the context
       | of the outer function. Nested functions should probably be very
       | short. And their only goal should be to make the outer function
       | logic more readable/understandable. It's not something I use a
       | lot but I've found a few uses for this. There's no point to using
       | nested functions other than for readability.
       | 
       | And speaking of Kotlin, it's standard library is full of very
       | small extension functions. Most of them are one or two lines.
       | They are clearly valuable because people use them all the time.
       | You get such gems as fun List.isNullOrEmpty(): Boolean which
       | helps make your if statements a lot more readable and less flaky.
       | Also works on Java lists. Stuff like that is a big part of why I
       | like Kotlin.
       | 
       | I tend to dumb down a lot of advice like both are debating here
       | to cohesiveness and coupling. In the context of functions, you
       | get coupling via parameters and side effects (e.g. modifying
       | state via parameters) instead of return values. And you lose
       | cohesiveness if a single function starts doing too many not so
       | related things. High coupling and low cohesiveness usually means
       | poor testability. You'll find yourself mocking parameters just to
       | be able to test a function. Improving testability is a valid
       | reason for extracting smaller, easier to test functions.
        
       | imjonse wrote:
       | I am biased ( a former coworker was an Uncle Bob fan, and was
       | bent on doing everything by the book, with layers of abstraction,
       | patterns, hexagonal architecture, lots of unit tests, no cutting
       | corners, even as we did not know what exactly we want to build
       | and needed an MVP ASAP) but I'll just say this: Ousterhout wrote
       | TCL - widely considered one of the best C codebases - besides
       | being a professor at Standford and having other software
       | achievements under their belt, while Robert Martin is more like a
       | software technology evangelist. The former good at actual
       | deliverables the latter good at selling.
       | 
       | Also Ousterhout's book on design is very easy to read and I guess
       | I liked it because I mostly just nodded in approval while reading
       | and there were very few things that made me stop.
        
         | begueradj wrote:
         | Let's not forget that Uncle Bob, by the time of writing "Clean
         | Code" had 4 decades coding experience.
        
           | kragen wrote:
           | My middle school English teacher had 4 decades of experience
           | writing. What she wrote was lesson plans. That doesn't make
           | her Stephen King.
        
           | WillAdams wrote:
           | Do not make the mistake of the craftsman who claims to have
           | 20 years of experience, but in truth only has 1 year of
           | experience repeated 20 times.
        
           | wglb wrote:
           | Are there large code bases that he has written that we know
           | anything about?
        
           | intelVISA wrote:
           | Software is results driven, there's no value in simply
           | warming a seat for X YOE, talking about code instead of
           | actually executing.
        
           | throw16180339 wrote:
           | What has he shipped, though?
        
           | mbonnet wrote:
           | Kenneth Copeland has been a pastor for 50 years and his
           | theology and pastoral practice is still terrible. Years of
           | experience is not a useful metric when you could instead look
           | at results.
        
         | j_san wrote:
         | Biased against the approach of your former coworker and thus
         | the "Clean Code" way? I assume it did not work out well,
         | because you needed to move fast to build an MVP before trying
         | to do it right?
        
           | imjonse wrote:
           | yes, biased against knowing 'the best way do write software'
           | and applying it regardless of what the current requirements
           | and constraints are. And arguing for their position by
           | sending people links to Uncle Bob videos for 'enlightenment'.
        
       | LunicLynx wrote:
       | The example they use is irrelevant. A solved problem can be
       | written how ever one likes.
       | 
       | Code that will change or can't ever be considered final, is the
       | real challenge.
       | 
       | Overly cutting code into methods makes code just rigid. This
       | could be the point, I guess, but if you need to change the
       | methods name in order to reflect the methods intent, than you
       | just wrote the classic unhelpful comment of:
       | 
       | // check a is not null
       | 
       | if (a != 0) { ... }
       | 
       | Overuse of comments has the same issue as overuse of methods.
       | 
       | Without rigor, comments and methods names will start to lie.
       | 
       | Because their content / name weren't necessary to understand the
       | code. And should just not exist in the first place.
        
       | pjmlp wrote:
       | All great, but generaly useless in most big corp project with
       | offshoring, where we are already happy that we actually delivered
       | something that works in first place.
        
       | nickm12 wrote:
       | This was a fun read. I read APoSD for the first time a couple of
       | months ago and found myself nodding enthusiastically as I read. I
       | have a few quibbles, of course, but overall it matches my
       | experience in how to write software that is correct,
       | maintainable, extensible, and understandable.
       | 
       | I've never read CC, but I've read some of the take downs[1]. I
       | was worried that the take downs were attacking a strawman, but
       | no, Uncle Bob believes this stuff, including that comments are
       | evil and you just need to read all the code and keep it in your
       | head.
       | 
       | Even if that were true, the code I write is better for having
       | written the comments, especially interface comments, because the
       | writing helps my thinking. Moreover, it helps my code reviewers--
       | without written interfaces. If all you have is the code and not a
       | description of what the code is supposed to do, how can you know
       | if it is correct? I think most code reviewers are verifying the
       | code against what they infer the interface to be. It helps us
       | both to just be explicit.
       | 
       | [1]: https://qntm.org/clean
        
       | nickm12 wrote:
       | buried at the end: there's a planned second edition of Clean
       | Code! Given Bob's intransigence in this conversation, I wonder
       | what he'll change.
        
       | ninetyninenine wrote:
       | Cleanliness AND Design is Highly correlated with IO, side effects
       | and state.
       | 
       | Most programmers know about this in 2025 but they didn't back
       | then. Looks like the authors don't even mention it.
        
       | dgunay wrote:
       | I find it funny how much people obsess over Clean Code. In my
       | opinion Robert Martin's Clean Architecture is a much more
       | valuable and realistic idea than all this madness about 3 line
       | functions, no comments, do one thing, etc. I would take the
       | ugliest code that followed Clean Architecture over any "Clean
       | Code" that didn't bother sensibly separating business logic and
       | I/O.
       | 
       | I don't like the guy very much, but for web development even just
       | mostly following Clean Architecture does so much to keep things
       | from devolving into chaos long term.
        
       | blt wrote:
       | The prime number code hurts to read. I feel like Bob is living in
       | a different reality than most of us.
        
         | jonashus wrote:
         | Yes, no, I think he has different mental capabilities than most
         | (most of the commenters here at least) and by that actually are
         | living in a different reality. Human brains function vastly
         | different. Two examples stood out to me.
         | 
         | 1) UB said he reads the code in its full from left to right
         | with the if(isTooHot) example. I only resort to reading code in
         | that way as a last resort if I really can't figure out what the
         | code is doing. I mean I look at a block or row and take it in
         | more as a whole.
         | 
         | 2) UB said comments are annoying because he has to read them
         | and keep the whole of the comment text in his mind. This again
         | says he reads everything left to right, and he can likely store
         | everything that he has read up to a certain amount.
         | 
         | My mind works nothing like that. I can hold very few words in
         | my working memory but can instead hold concepts/ideas. For that
         | to work good I need to see as much of the involved code as
         | possible and my mental image evaporates if I have to navigate
         | too far where I started.
        
       | myst wrote:
       | Where can I find Martin's code? I would like to see and compile
       | it.
        
         | brodo wrote:
         | https://github.com/unclebob/fitnesse
        
       | sharas- wrote:
       | Whoes uncle is he anyways?
        
       | jacobsenscott wrote:
       | I was around before the clean code movement, and like all
       | software movements, it was a reaction to real problems in the
       | software industry. Massive procedural functions with deeply
       | nested conditionals, no structure, global variables, no testing
       | at all. That was all the norm.
       | 
       | Clean Code pushed things in a better direction, but it over-
       | corrected. In many ways APOSD (published in 2018) is a correction
       | against the excesses of Clean Code (published in 2008).
       | 
       | Will people swing too far back, to giant methods, deeply nested
       | conditionals, etc? I don't know. But probably.
        
         | matsemann wrote:
         | I think learning extremes can be useful, just don't take any
         | one paradigm as gospel. Practicing Clean Code forces you to
         | think in a special way, and when you've tried it, you start to
         | get a feeling for where you should draw the line. Doing CC
         | makes you a better programmer, but you have to figure out
         | yourself where the tradeoffs are.
         | 
         | Other examples are TDD. Forcing myself to write tests for
         | everything for a period has made all my code since better, even
         | though I don't practice TDD now.
        
           | lyu07282 wrote:
           | I feel the same way, the benefit of testing is that it forces
           | you to write code that can be tested, which tends to make
           | code better just in general.
        
         | k__ wrote:
         | If you don't nest that much, big functions aren't so bad.
         | 
         | You can just scroll down and see what happens in a linear
         | fashion.
        
           | pclmulqdq wrote:
           | This is the Linux kernel approach, and is a big part of why
           | the kernel uses 8-space tabs. It's generally very effective
           | for understanding what is happening. I'm happy with a
           | 200-line straight-line-with-error-handling function, while a
           | monstrosity of 10 20-line functions that all do if-else is
           | quite a bit harder to read. The latter is "clean code."
        
         | abirch wrote:
         | As Ben Franklin wrote "the best physician that knows the
         | worthlessness of the most medicines."
        
         | regularfry wrote:
         | I believe that there is a genuine physiological effect that
         | makes it a good idea to have the area of code that you need to
         | think about fit entirely on one screen, without scrolling.
         | There is probably an upper limit to the screen height where
         | that limit is useful: I would believe a 100-line function to be
         | above it and a 24-line function to be safely below it, but I
         | wouldn't want to hazard a guess in the middle.
         | 
         | It's all to do with how your brain processes what it's seeing,
         | and the planning processes involved in getting to the next bit
         | of information it needs. If that information is off-screen,
         | then the mechanisms for stashing the current state and planning
         | to move your hands in whatever way necessary to bring it
         | onscreen will kick in, and that's a sort of disfluency.
         | 
         | Similarly with tokens too far from whatever you're currently
         | focused on. There's likely to be a region (or possibly a number
         | of tokens) around your current focal point within which your
         | brain can accurately task your eyes to scan, and outside that,
         | there's a seeking disfluency.
         | 
         | I think this is why you get weird edge cases like k and j,
         | where they pride themselves on having All The Code in one 80x24
         | buffer, and it _actually works for them_ despite breaking all
         | the rules about code legibility.
        
           | tremon wrote:
           | The term you're looking for is cognitive load. It's a
           | qualitative term used to represent the amount of information
           | a person has to keep in working memory while working on a
           | task.
        
       | coopykins wrote:
       | As someone who's recently started to read a philosophy of
       | software design, I have to say that a lot of the points the
       | author makes are things that I've come to learn with experience,
       | which feels pretty good. As opposed to clean code, which I read
       | when I was starting, and although at that time it felt good to
       | have some guidelines--I still think having some guidelines is
       | better than having nothing at all.
       | 
       | I think you grow out of that advice very soon, because it's not
       | very practical, it feels out of touch. The result is not code
       | that is easier to read, quite the contrary. I think the Java
       | world has been influenced for worse by him.
       | 
       | But I don't have anything against him, as other comments say, the
       | problem is dogmatism and trying to follow these authors blindly
       | instead of thinking about it.
        
       | wg0 wrote:
       | The arguments from staunch clean code zealots have wasted so much
       | time on PRs that I have lost count. Hours and hours and sometimes
       | weeks - PRs having ideological discussions on something that
       | neither the underlying machine cares nor the end user.
       | 
       | Multiply that across the industry and that probably easily
       | reaches in hundreds of millions of dollars productivity wasted.
       | 
       | Ps: Not advocating cowboy coding or spaghetti code either.
        
       | Copenjin wrote:
       | You just need to work on one project built by someone that
       | implemented Uncle Bob recommendations blindly when the books came
       | out to know how much they are worth. There were some low hanging
       | fruits to pick at the time regarding trying to be better at
       | software engineering and he generated some text about them.
       | 
       | Full of terrible advices, he never wrote anything significant (in
       | scope and notoriety) during his time as a software engineer like
       | many other prominent authors at the beginning of the agile era.
       | The success is only the result of a wave of junior devs searching
       | for some sort of guidance, something that there is a never-ending
       | need for.
       | 
       | Horrible recommendations that produced a lot of code that is a
       | pain to work on with the abundant amount of indirection it has.
       | Really painful guys.
        
         | __loam wrote:
         | A Philosophy of Software Design on the other hand is concise,
         | excellent, and based on decades of teaching experience.
        
           | k__ wrote:
           | The world isn't binary
        
             | mbonnet wrote:
             | what's your point?
        
               | k__ wrote:
               | I interpreted the comment as sarcasm.
        
           | kragen wrote:
           | More importantly, experience writing great software.
        
           | mdaniel wrote:
           | If I win the lottery, I don't want a building named after me
           | I want to donate a copy of that book to every university
           | computer science[1] student and make it required reading
           | 
           | 1: I'm aware it's a _software engineering_ book, but since
           | there are very few B.S. Software Engineering programs out
           | there, You Know What I Mean  &trade;
        
         | wiether wrote:
         | > The success is only the result of a wave of junior devs
         | searching for some sort of guidance, something that there is a
         | never-ending need for.
         | 
         | The issue is that, some never grown out of it. I interviewed
         | with companies where they give the book to any new
         | intern/junior. Then, during the hiring process, they don't even
         | ask if you read it, they straight up ask questions about your
         | knowledge of it. Like "What does Uncle Bob says about X in his
         | book Clean Code?". And they constantly refers to it. Some
         | people go as far as quoting it in PR.
         | 
         | The worst part being that once they leave their company, since
         | they don't know anything else, they'll apply the same stuff
         | elsewhere & convert their new company to it.
        
         | jbreckmckye wrote:
         | (English tip: advice isn't a countable noun, so you don't
         | pluralise it)
         | 
         | I agree entirely. My encounters with Uncle Bob were as a junior
         | developer receiving advice [no "s"] from other junior
         | developers.
         | 
         | And yes, I too find it suspicious how many mavens of the "Agile
         | era" never really managed to ship anything.
        
           | disgruntledphd2 wrote:
           | It's important to note that Kent Beck is not one of those
           | people, as he shipped the first unit testing library, as well
           | as a bunch of ones in other languages later.
           | 
           | Like, I personally prefer the bare assert style of testing
           | (like pytest), but the junit style is basically everywhere
           | now.
        
             | machine_ghost wrote:
             | Kent Beck is just as bad as Uncle Bob! He drank his own
             | proverbial Kool-Aid and went all in on the crazy XP
             | programming fad he started (... which contains brilliance
             | like requiring pair programming for every line of code
             | written).
             | 
             | Look, both authors are very smart people who have great
             | insights into development that we can all learn from ...
             | but both also have the failing of being way too in love
             | with their own ideas.
             | 
             | It blinds them to the flaws in those ideas, and makes it so
             | when you read their work you _have_ to be skeptical and
             | evaluate each individual idea on their own.
        
           | Copenjin wrote:
           | Thanks for the correction, my opinion on the lack of
           | credentials is that in the early days you just didn't need
           | them to become popular, so little content that no one
           | checked. I bit like it's happening nowadays with the anime
           | profile pic twitter accounts acting like they invented AI,
           | with zero code or achievements being shown.
        
         | dgb23 wrote:
         | Clean code, design patterns etc. were also picked up by
         | teachers, professors and course instructors.
         | 
         | I think these paradigms and patterns often operate on the wrong
         | layer of abstraction, while mostly ignoring the things that
         | matter the most, like efficiency, error handling and debugging.
         | 
         | But getting good at these things requires a lot more blood,
         | sweat and tears, so there's no easily teachable recipe for
         | that.
        
           | bluGill wrote:
           | Clean Code is trying to operate at a layer far more important
           | than efficiency: code maintenance. In the vast majority of
           | cases computers are fast enough that you don't need to worry
           | about efficiency. (part of this is any modern language
           | provides all the common algorithms that are already highly
           | optimized and easier to use than the writing them by hand and
           | so the common places where you would want to worry are
           | already efficient).
           | 
           | Of course error handling and debugging are part of
           | maintenance. However there is a lot more than those two that
           | need to be considered as well.
           | 
           | There is reason to hate Clean Code, but the worst adherents
           | to the rules are still producing far better code than some of
           | the impossible stuff that happened before. "Goto considered
           | harmful" is one of the early steps in fixing all the bad
           | things programmers used to do (and some still do), but you
           | can follow the "rules" of goto considered harmful and still
           | produce really bad code so we need more.
        
             | dgb23 wrote:
             | From personal experience, the most time consuming
             | maintenance issues arise because of the following things:
             | 
             | - third party dependencies, compatibility issues, breaking
             | changes
             | 
             | - code that is bloated with abstractions and indirection
             | 
             | - performance issues, especially when worked around via
             | caching etc.
             | 
             | - bad error handling
             | 
             | - inconsistent data
             | 
             | Simpler code that can be followed and stepped through in a
             | straight forward manner avoids 3/5 of these from the get
             | go. Patterns and abstractions that emerge over time are
             | sometimes beneficial. Legacy code or third party code that
             | overuses abstractions is really more of a hindrance and
             | significantly slows down how fast I can understand, own and
             | fix things.
        
               | bluGill wrote:
               | It sounds like you have been lucky enough to avoid some
               | of the worst code practices of history. Good for you.
               | 
               | I hope you can come up with a good answer to fix the
               | problems you cite. I haven't seen anything I have
               | confidence in.
        
         | Scubabear68 wrote:
         | It is very instructional to read the source code to FitNesse
         | framework.
         | 
         | https://github.com/unclebob/fitnesse
         | 
         | You can see how all his ideas come together into a ball of
         | hundreds of almost empty classes, and gems such as "catch
         | Throwable".
        
       | lynguist wrote:
       | This was such a riveting and literary read, I enjoyed it and
       | couldn't put it away, like a novel where I was invested in the
       | characters!
       | 
       | Are there any other such reads in the software engineering field?
        
         | WillAdams wrote:
         | Knuth?
         | 
         | He has argued in the past that the concept of Literate
         | Programming
         | 
         | http://literateprogramming.com/
         | 
         | is the most important work he has done, and I highly recommend
         | his various collections of lecture notes/papers including:
         | 
         | https://www.goodreads.com/book/show/112245.Literate_Programm...
        
         | wglb wrote:
         | A Discipline of Programming, Dijkstra
         | 
         | The architecture of Concurrent Programs, Per Brinch Hansen
         | 
         | Literate programming--see http://www.literateprogramming.com/
         | 
         | I don't recommend Design Patterns, as these are elements needed
         | if your programming language is inadequate.
         | 
         | There are many more.
        
       | ilitirit wrote:
       | It still blows my mind how dogmatic some people can be about
       | things like this. I don't understand why anyone takes these
       | things as gospel.
       | 
       | Who else has had to deal with idiots who froth at the mouth when
       | you exceed an 80 line character margin?
       | 
       | And it's not just programming styles, patterns and idioms. It's
       | arguably even worse when it comes to tech stacks and solution
       | architecture.
       | 
       | It's super-frustrating when I'm dealing with people in a
       | professional setting and they're quick to point out something
       | they read in a book, or even worse - a blog - with very little
       | else to add.
       | 
       | This was especially bad during the NoSQL and Microservice hype.
       | Still somewhat feeling it with PAAS/SAAS and containerization. We
       | have so many really really basic things running as Function Apps
       | or lambdas, or simple transformations running in ADF or Talend
       | that add zero value and only add to the support and maintenance
       | overhead.
       | 
       | Always keep in mind that sometimes the only difference between
       | yourself and the person writing the book/blog/article is that
       | they actually wrote it. And that their opinions were written down
       | don't make them fact. Apply your own mind and experience.
        
         | hdkrgr wrote:
         | >> Always keep in mind that sometimes the only difference
         | between yourself and the person writing the book/blog/article
         | is that they actually wrote it.
         | 
         | Well said!
        
         | abirch wrote:
         | Remember when most people give presentations about a
         | technology, they're in the honeymoon stage
        
         | raverbashing wrote:
         | > Who else has had to deal with idiots who froth at the mouth
         | when you exceed an 80 line character margin?
         | 
         | Honestly, no better indication of a very mediocre developer
        
           | einpoklum wrote:
           | My experience is that being fastidious about code formatting
           | is independent of one's ability as a developer. i.e. not a
           | good indicator either way.
        
             | bena wrote:
             | I've noticed the worse someone is in a language, the worse
             | they format it.
             | 
             | People then develop fastidious code formatting rules
             | because they realize well formatted code is easier to read
             | and extend.
             | 
             | Then people realize it's the organization of the code, not
             | the rules themselves. They have preferences, but don't
             | treat those preferences as "the one true way".
             | 
             | So people with fastidious rules are in that middle ground
             | of becoming less bad, and that's a wide swath of abilities.
        
               | raverbashing wrote:
               | > Then people realize it's the organization of the code,
               | not the rules themselves. They have preferences, but
               | don't treat those preferences as "the one true way".
               | 
               | Yup, I agree with this
               | 
               | It's not about, let's say, where your curly braces stay,
               | but being consistent
               | 
               | Though in some cases I'd argue that things like a very
               | strict 80 character limit actually results in worse code
               | (or at least worse to read code)
        
               | ninetyninenine wrote:
               | Disagree. Highly disagree.
               | 
               | Smarter people write shittier code.
               | 
               | Clean code is for stupider people.
               | 
               | Think about it. It's because smart people don't need
               | clean code. It's so trivial to them and so readable that
               | they really don't need things to be ultra clean and well
               | formatted.
               | 
               | So the tendency to have this ocd need to write clean code
               | among smart people is random. They either have it or they
               | don't give a shit.
               | 
               | But among stupid people it's not random. They need clean
               | code because they are not smart enough to understand code
               | that isn't clean.
        
               | holoduke wrote:
               | Reality is that you have to work with different levels of
               | intelligence. Your stack must be understandable also for
               | the "common" programmer. Otherwise goodluck finding
               | people.
        
               | ninetyninenine wrote:
               | True. But what I said is still true. The tendency exists.
               | 
               | Smart people don't often know how smart they are and
               | don't realize how unreadable their code is until code
               | review time and the stupid person points out what the
               | smart person considered "obvious"
        
               | Ma8ee wrote:
               | Or maybe the smartest people understand that it is as
               | important that less smart/experienced people than them
               | can work with the code.
        
               | ninetyninenine wrote:
               | No. This what stupid people who think they are smart tend
               | to think.
               | 
               | Smart people often don't realize how smart they are and
               | they don't recognize there code as unclean. To them it's
               | trivial.
               | 
               | A lot and I mean a lot of people on HN think they are
               | smart but they are actually average or stupid. The amount
               | of smart people operating at that level is rare. Really
               | rare. I've been at entire companies where there isn't one
               | person who is actually "smart" at the level I describe.
               | Most people are just average.
        
               | jjj123 wrote:
               | Okay so your definition of "smart" sounds different than
               | the definition everyone else in this thread is using.
               | Sounds more like you're talking about "genius" to me,
               | specifically in a savant type way where they are
               | incapable of relating to average people.
        
               | ninetyninenine wrote:
               | No. I'm talking about genius. Not savant. Savants likely
               | can't relate to your emotions. Geniuses can. The
               | difference is just if it takes them 1 second to parse
               | what takes you 5 minutes to do the same they often don't
               | realize this unless you tell them.
               | 
               | That being said what I talk about lives on a gradient.
               | The smarter you are the greater degree of tendency you
               | have to write shitty code.
               | 
               | The cleaner your code the higher possible chance you are
               | stupider. It's not a definitive sign but there is a
               | correlation.
        
               | ddejohn wrote:
               | This is the silliest thing I've ever heard
        
               | ninetyninenine wrote:
               | Probably because you think you're smart AND you write
               | excessively clean code and are excessively anal about it.
               | Whether you actually are smart is a different story.
        
               | ddejohn wrote:
               | You have constructed a representation of me in your head
               | that in no way reflects reality. Good luck in life.
        
               | ninetyninenine wrote:
               | It's just a lucky guess.
        
               | dkarl wrote:
               | I've been trying for years to track down a quote I lost,
               | and it sounds like something you might know, because I
               | think it would have resonated with you.
               | 
               | It was from Charles Simonyi, talking about how as he got
               | older, his prodigious ability to juggle large amounts of
               | information in his head declined, and as a result, he
               | started writing better code. Do you know it?
               | 
               | Also, I half agree with your point, but I see it happen
               | in two different ways. When writing ad hoc code for
               | research purposes, I see very gifted people write
               | seemingly sloppy, to-the-point code because it's the
               | quickest way to the result. I say _seemingly_ sloppy
               | because another programmer would see an intricate
               | mechanism that in so many places is a hair 's breadth
               | from being wrong, and they would want to reorganize it to
               | make it more obvious that the code is correct. The savant
               | who wrote the code is like, it's already 100% obvious,
               | how could any change make it more obvious than that?
               | 
               | In the software development context, I sometimes see very
               | gifted people write incredibly complex code because they
               | enjoy flexing their intellectual muscles and seeing the
               | ornate towers they can create. But I also see average
               | programmers and dumb programmers do the same thing, the
               | only difference being that the gifted people can get away
               | with more before it starts to hurt them. What's more, I
               | see very good engineers, gifted but not _as_ gifted, try
               | to follow the example of a savant and end up
               | accomplishing far less than they could if they cut
               | themselves a break and wrote plain code without all the
               | flourishes and ornaments. A gifted programmer usually
               | gets tired of this and grows out of it, but some of them
               | enjoy it so much they commit to fooling themselves and
               | other people that it 's the right way to write software.
               | 
               | > So the tendency to have this ocd need to write clean
               | code among smart people is random
               | 
               | It is if they work entirely alone and their work doesn't
               | depend at all on the success of others using their code.
               | However, when it comes to big software projects, my
               | experience is that it's not random: the smartest people
               | do end up writing good code, unless they have ulterior
               | motivations or a severe social blind spot.
        
               | ninetyninenine wrote:
               | Yeah they learn. But the tendency is still there. They
               | make an attempt to dumb down their code but often they
               | prioritize speed and what works.
        
               | bena wrote:
               | That's definitionally untrue.
               | 
               | Shitty code doesn't run or doesn't do what the author
               | thinks it's supposed to do. You can't write genuinely
               | shitty code and be smart.
               | 
               | I've seen smart people get caught in trying to write
               | "clever" code. Abusing features of a language to make the
               | code "look" smart. And I've never seen someone I've
               | considered smart write completely unformatted code where
               | it matters.
               | 
               | I may not agree with all of their choices, but the
               | smartest people I've worked with tend to have the
               | structure of the code reflect the structure of the
               | problem as they see it in their head. And yes, that
               | tracks, you begin to use the code itself as an assistant
               | to your own thinking. You don't think about where things
               | are because they are where they should be.
               | 
               | Forcing yourself to remember a bunch of pointless
               | minutiae in order to write software isn't a mark of
               | intelligence, it's a mark of someone who wants to be seen
               | as intelligent.
        
               | ninetyninenine wrote:
               | >Shitty code doesn't run or doesn't do what the author
               | thinks it's supposed to do. You can't write genuinely
               | shitty code and be smart.
               | 
               | By shitty code I mean aesthetically shitty. Not
               | intrinsically shitty. So definitionally true, depending
               | on your definition. Obviously I'm talking and I
               | established context so most readers can figure out that
               | I'm utilizing MY definition and NOT your own.
               | 
               | >I've seen smart people get caught in trying to write
               | "clever" code. Abusing features of a language to make the
               | code "look" smart. And I've never seen someone I've
               | considered smart write completely unformatted code where
               | it matters.
               | 
               | Then you've never been around the smartest people. Likely
               | you've been around smarter then average people.
               | 
               | >I may not agree with all of their choices, but the
               | smartest people I've worked with tend to have the
               | structure of the code reflect the structure of the
               | problem as they see it in their head. And yes, that
               | tracks, you begin to use the code itself as an assistant
               | to your own thinking. You don't think about where things
               | are because they are where they should be.
               | 
               | Yeah and the smartest people structure the problem in
               | their head in a way normal people can't easily
               | understand. They can hold much more in their head so the
               | structures can be complex.
               | 
               | >Forcing yourself to remember a bunch of pointless
               | minutiae in order to write software isn't a mark of
               | intelligence, it's a mark of someone who wants to be seen
               | as intelligent.
               | 
               | Isn't that my point? Formatting rules are a bunch of
               | pointless minutiae to intelligent people. It doesn't
               | assist them in readability because their intelligence
               | allows them to parse even the shittiest code with
               | complete ease. And I mean aesthetically shitty, not
               | intrinsically shitty.
        
               | bena wrote:
               | Then say ugly. "Shitty" can be ambiguous as you see. Most
               | people would classify buggy code as shitty code.
               | 
               | > Then you've never been around the smartest people.
               | Likely you've been around smarter then average people.
               | 
               | This is essentially using your own belief as proof that
               | your belief is correct. You say I haven't been around the
               | smartest people because I say the smartest people don't
               | do what you claim. You are saying "I'm right therefore
               | you are wrong". Maybe _you_ haven 't been around the
               | smartest people.
               | 
               | > Yeah and the smartest people structure the problem in
               | their head in a way normal people can't easily
               | understand. They can hold much more in their head so the
               | structures can be complex.
               | 
               | Complex is easy. Simple is hard. And yes, some things are
               | inherently more complex than others. But the goal is to
               | hold the _important_ things in your head. Offload as much
               | as you can so you can focus on what matters.
               | 
               | > Isn't that my point? Formatting rules are a bunch of
               | pointless minutiae to intelligent people. It doesn't
               | assist them in readability because their intelligence
               | allows them to parse even the shittiest code with
               | complete ease. And I mean aesthetically shitty, not
               | intrinsically shitty.
               | 
               | No. It's not the point you are making.
               | 
               | Also, look at to everything I said. Strict adherence to
               | any one style is not a marker of intelligence. I
               | explicitly said that strict adherence is essentially for
               | people in a wide range of skills. But the best have
               | preferences, but realize that they are more guidelines
               | and readability matters more than the rules.
               | 
               | And the rules should be logical and essentially second
               | nature. Like indenting is completely optional in most
               | languages. But proper indenting allows you to better
               | visualize the flow of the code. Nobody reads/writes
               | minified JavaScript.
        
               | ninetyninenine wrote:
               | >This is essentially using your own belief as proof that
               | your belief is correct. You say I haven't been around the
               | smartest people because I say the smartest people don't
               | do what you claim. You are saying "I'm right therefore
               | you are wrong". Maybe you haven't been around the
               | smartest people.
               | 
               | I have quantitative evidence of this. There IQs were
               | above 150.
               | 
               | >Complex is easy. Simple is hard. And yes, some things
               | are inherently more complex than others. But the goal is
               | to hold the important things in your head. Offload as
               | much as you can so you can focus on what matters.
               | 
               | complex is not easy. And simple is not necessarily always
               | hard. The story is obviously more complex then this.
               | 
               | >No. It's not the point you are making.
               | 
               | It is. It was a rhetorical question.
               | 
               | I looked at everything you said. First off I never said
               | anything about strict adeherence to a style. Smart people
               | have there preferences.
               | 
               | >And the rules should be logical and essentially second
               | nature. Like indenting is completely optional in most
               | languages. But proper indenting allows you to better
               | visualize the flow of the code. Nobody reads/writes
               | minified JavaScript.
               | 
               | I've seen smart people who can do this. They don't even
               | really care.
        
               | bena wrote:
               | You are just making more claims. You _claiming_ their IQs
               | were above 150 does not mean they were. Or that you aren
               | 't just straight up making wild claims to try and bolster
               | your point.
               | 
               | Also, how would you even know their IQs? I went to the
               | best high school in my state, one of the best high
               | schools in the nation, that became the template for an
               | entire class of high performing high schools today. I
               | don't say this to brag. I say this to qualify my next
               | statement. I couldn't tell you what the IQ was of anyone
               | there. It is not something that ever comes up.
               | 
               | > First off I never said anything about strict adeherence
               | to a style. Smart people have there preferences.
               | 
               | This is directly counter to your other claims. You say
               | that smart people just write ugly code and don't care
               | about formatting. You even say that later in this post.
               | It's almost like you are saying whatever you think will
               | make you right in the moment.
               | 
               | You also claim to have looked at everything I said, but
               | your statements here contradict that. Because I said the
               | best have preferences and follow a style, but know that
               | there are times when the rules are counter to the goal.
               | 
               | And you may actually believe you've seen smart people who
               | can do this. However, at this point, I doubt your ability
               | to accurately judge anyone's skill or intelligence. Or
               | the ability to judge the veracity of their claims.
        
               | ninetyninenine wrote:
               | It came up because we talked about Mensa and he was part
               | of it. I asked his iq and he told me. He claimed it and I
               | believe him. Then the other guy also said he was offered
               | to join Mensa but didn't. Take from that what you will.
        
               | colonCapitalDee wrote:
               | > Then you've never been around the smartest people.
               | Likely you've been around smarter then average people.
               | 
               | This is totally unfalsifiable. I claim that the smartest
               | people around always wear clown shoes to work. If you
               | disagree, it's simply because you haven't met any of the
               | people I'm talking about. QED
        
               | Pxtl wrote:
               | When you're writing it you have the help of the compiler
               | and various other tools, plus you have the model of what
               | the code is doing fully-formed in your head, and you have
               | the recent memory of various other approaches you took
               | and how and why they failed. When you're reading it you
               | have none of those things.
               | 
               | So, code is harder to read than it is to write.
               | 
               | So if you write code that uses your full intellect to
               | write it out, you are therefore by definition too dumb to
               | read it.
        
               | ninetyninenine wrote:
               | I never said smart people are writing code with their
               | full intellect.
               | 
               | They are likely writing code with a fraction of their
               | intellect and that code is still too complicated for
               | normal people to comprehend.
        
             | ChrisMarshallNY wrote:
             | The best developer that I ever worked with, is "on the
             | spectrum."
             | 
             | His code was _really_ anal.
             | 
             | I have come to learn that there are no "rules," only
             | heuristics.
        
             | amoss wrote:
             | I can't remember the last time I worked on a team without
             | automatic linting enforced on check-in. Why would people
             | choose to waste time arguing over that can be automated?
        
         | Lyngbakr wrote:
         | > It still blows my mind how dogmatic some people can be about
         | things like this. I don't understand why anyone takes these
         | things as gospel.
         | 
         | IMO, this is one of the key differences between the two books.
         | CC has a vibe of hard and fast opinion-based rules that you
         | must obey, whereas APoSD feels more like empirically-derived
         | principles or guidelines.
        
           | pclmulqdq wrote:
           | APoSD is written by a highly respected computer scientist
           | with a tremendous list of technical achievements and also a
           | strong teaching history as a professor, while CC was written
           | by someone whose resume is primarily related to writing about
           | software, not writing software.
        
             | wangvnn wrote:
             | CC was written by a man who worked with a highly respected
             | man .. let that sink :)
        
         | wesselbindt wrote:
         | > idiots who froth at the mouth
         | 
         | That seems like an unnecessarily harsh way to refer to people.
        
           | codesnik wrote:
           | but... they do froth!
        
           | ahoka wrote:
           | Well, except "Clean Code" advocates.
        
           | felizuno wrote:
           | Clean Code zealots are consistently some of the least
           | likable, least productive, least pragmatic people I have ever
           | worked with. I've had multiple clients where the whole team
           | is threatening to quit unless the CC zealot is fired. And
           | when they are fired guess what - bugs go down, shipped
           | features go up, and meetings become productive. "Idiots who
           | froth at the mouth" is an understatement IMO
        
             | wesselbindt wrote:
             | This too seems like a fairly hardline stance to take. I
             | think it's not surprising that you'd have a hard time
             | collaborating with people you'd refer to as unlikeable,
             | unproductive, unpragmatic, overzealous, frothy idiots.
             | 
             | It reminds me of the standard joke about veganism: "how do
             | you know someone is vegan? Don't worry they'll tell you"
             | 
             | It's a very ironic joke, because the people I hear talking
             | about veganism the most are non-vegans complaining about
             | veganism. In this thread too. All I see is people
             | complaining about how dogmatic clean code people are, and I
             | see no examples of that in this thread. The only strong and
             | absolute language I see is from those who are complaining
             | about CC people.
             | 
             | Bear in mind, I don't have a dog in this fight. I'm not
             | vegan, my methods are sometimes longer than four lines, and
             | I do occasionally write a comment. But if this thread is
             | anything to go by, the clean code folks seem a lot nicer to
             | work with than the reactionaries.
        
               | ramon156 wrote:
               | On top of that, the argument was "i hate clean code
               | people because they use bad reasoning (read something in
               | a blog)". These are exclusive from each other. The OC
               | basically argued there are no good reasons for clean
               | code.
               | 
               | I prefer readable code, but I wouldn't call myself a
               | "clean code" person.
        
               | felizuno wrote:
               | I am in here taking a strong stance against CC, but I am
               | happy to agree with you and steel-man your point: I think
               | Clean Code is perfectly fine and workable in academic and
               | single-developer software projects.
               | 
               | I think most of this pushback (certainly all of mine) is
               | about it creeping into production environments and
               | exacerbating personality traits that tend to be
               | problematic in team settings, which does not invalidate
               | the abstract idea and should instead be scoped to its
               | practice.
        
               | felizuno wrote:
               | I'm not seeking these people out to hate on them, but
               | when I encounter them the social and code environments
               | around them always exhibit the same dysfunctions. I've
               | seen it multiple times. When your team is threatening to
               | quit because they can't stand working with you, the
               | problem is _probably_ with you and not them. And when you
               | get fired and bugs go down, velocity goes up, and the
               | morale problems disappear, it's now obvious that the
               | problem was you. It's not a hand wavy theoretical take,
               | it's a consistent pattern from dozens of instances at a
               | variety of companies.
        
               | arp242 wrote:
               | Well I am vegan, and let me tell you, some vegans are
               | completely insufferable. While it's true that the people
               | ranting about vegans outnumber the insufferable vegans,
               | there is a core of truth to it.
               | 
               | I didn't read all 416 comments in this thread, but I've
               | definitely worked with some people who religiously follow
               | Clean Code to the point of toxicity. Perhaps the most
               | bizarre example I encountered was the person who insisted
               | that they're a backend dev, that they should never have
               | to open the UI to test anything as tests should always be
               | sufficient, and would continue pushing bugs in to
               | production because the early "startup days" had produced
               | some pretty crappy code with limited (or no!) tests. It
               | was completely unworkable. The team literally had a party
               | after he left. That was after two people had quit in
               | large part due to this person.
               | 
               | I have also worked with some people who generally liked
               | _Clean Code_ but didn 't follow it religiously in spite
               | of what works for this specific project. That's fine:
               | that's just a normal type disagreement like Python vs.
               | Ruby or where to put the braces or whatever: you talk to
               | each other, and reach some solution that reasonably works
               | for everyone.
               | 
               | And the "reactionaries" are mostly just normal folks who
               | want to get stuff done.
        
             | cluckindan wrote:
             | I've seen someone take a _glance_ at a codebase, declare it
             | too complex, and suggest reading Clean Code.
             | 
             | The entirety of the complexity was essential and dictated
             | by an external data model used nation-wide for
             | interoperability.
             | 
             | Based on my experience and the OP dialogue, Uncle Bob is a
             | vanity-driven narcissist and an infectious fraud.
        
           | yakshaving_jgt wrote:
           | Maybe they had mistaken "code" for "teeth"?
        
             | wesselbindt wrote:
             | Oh my goodness it took me 5 hours to get this. I'm glad I
             | finally did!
        
         | nicce wrote:
         | > Always keep in mind that sometimes the only difference
         | between yourself and the person writing the book/blog/article
         | is that they actually wrote it. And that their opinions were
         | written down don't make them fact. Apply your own mind and
         | experience.
         | 
         | But that difference is actually huge. I think you are
         | downplaying the value of the writing process. Assuming that
         | writer is acting in good faith and truly tries to provide the
         | best possible information.
         | 
         | But when you start writing, you start noticing that this idea
         | might not be that good after all. Maybe I need to read more
         | about this? Did you note everything? This idea conflicts with
         | this other topic than I just wrote? What is correct? And the
         | list goes on. When you structure all your thoughts as written
         | text, it is easier to detect all conflicting ideas and
         | mistakes. Not all writers are that good, but you should
         | understand what I mean.
        
           | __mharrison__ wrote:
           | Writing is an excellent way to determine your opinions.
           | There's a large gap between ideas and those formed when
           | writing said ideas.
        
         | hliyan wrote:
         | To restate something I've said here last month:
         | 
         | I'm fond of saying that anything that doesn't survive the
         | compilation process is not design but code organization. Design
         | would be: which data structures to use (list, map, array etc.),
         | which data to keep in memory, which data to load/save and when,
         | which algorithms to use, how to handle concurrency etc. Keeping
         | the code organized is useful and is a part of basic hygiene,
         | but it's far from the defining characteristic of the craft.
        
           | leidenfrost wrote:
           | My take is that the book also works as a source of authority
           | for aspiring SSR and SR devs.
           | 
           | Comments about code style are usually subjective, and, they
           | can be easily dismissed as a personal preference, or, in the
           | case of a Jr dev, as a lack of skill.
           | 
           | Until they bring up "The Uncle Bob book". Now, suddenly, a
           | subjective opinion from a Jr dev looks like an educated
           | advice sourced from solid knowledge. And other people now
           | have a reason to listen up.
           | 
           | All of this is totally fabricated, of course. But it's like
           | the concept of money. It's valid only because other people
           | accept it as valid.
        
             | tempodox wrote:
             | What are "SSR and SR devs"?
        
               | leidenfrost wrote:
               | Semi Senior and Senior devs
        
               | __mharrison__ wrote:
               | Is this a common usage?
        
               | mjr00 wrote:
               | I had never heard it and assumed it was gacha
               | terminology, with SSR devs as the top 1-2% and SR devs
               | top 20%.
        
               | nuancebydefault wrote:
               | Semi senior?
               | 
               | I usually tend to take people who add prefixes like
               | senior to their function title, less seriously. I've seen
               | young devs who write better code than so called senior
               | devs.
        
           | dkarl wrote:
           | > Keeping the code organized is useful and is a part of basic
           | hygiene, but it's far from the defining characteristic of the
           | craft.
           | 
           | I'm with you, but I don't think it makes sense to elevate one
           | absolutely over the other as the "defining characteristic."
           | Either one can tank the development of a piece of software
           | and prevent it from coming into being in a useful way.
           | 
           | Arguments about which aspects of software are more important
           | than others usually arise between people who have personally
           | suffered through different ways that projects can fail. Any
           | aspect of software development will feel like the "defining
           | characteristic" if it threatens to kill your project.
        
             | geodel wrote:
             | > Any aspect of software development will feel like the
             | "defining characteristic" if it threatens to kill your
             | project.
             | 
             | That does not make sense to me. There can be thousand
             | things that can kill project. One has to consider _what are
             | the odds_ for them.
        
               | dkarl wrote:
               | How would you define the odds for the industry as a
               | whole? The odds depend on the project, the team, the tech
               | stack, and the organizational environment.
               | 
               | No matter how long I work (twenty-five years so far) I
               | think my personal experience is only enough to know that
               | if I've seen something, it probably happens fairly often.
               | If I've never seen something, it still might be common
               | for all I know.
        
           | analog31 wrote:
           | Granted, while I program a lot, I'm not employed as a
           | programmer per se. My impression is that programming is easy
           | and fun, but software develoment is hard and laborious.
           | Things like hygiene are among the differences between the
           | two.
        
             | jolt42 wrote:
             | 100%. Dealing with legacy issues is much more laborious and
             | also complicates hygiene.
        
           | tikhonj wrote:
           | I disagree entirely. Design is fundamentally a human-oriented
           | discipline, and humans work almost exclusively with code
           | _before_ it is compiled. A strong shared mental model for
           | whatever we 're doing is as much a part of software
           | development as any code that runs on a computer.
           | 
           | Programming languages can (should!) be _amazing tools for
           | thought_ rather than just tools for making computers do
           | things; using these tools to figure out what we 're doing is
           | a critical part of effective development. The highest-
           | leverage software engineering work I've seen has involved
           | figuring out better ways of thinking about things: developing
           | better tools and abstractions. Tools and abstractions
           | _compound_ since they fundamentally impact everything built
           | on top of them. A good high-level design is the difference
           | between a team that can add some specific capability in a
           | day, a team that would take six months and a team that would
           | say it cannot be done.
        
             | mattmanser wrote:
             | I agree, I recently keep having the thought that by far the
             | hard part of programming is code organisation. Whether
             | that's where the files go, or how you've wrapped up
             | commonly used idioms like validation or data access in easy
             | to use abstractions.
             | 
             | It's so easy to get it spectacularly wrong and end up in a
             | mess.
             | 
             | And it's seems so deceptively pointless at the start. It's
             | easy to throw together a greenfield project and get
             | something working, but make a complete mess of
             | organisation. But then it becomes so expensive so quickly
             | to then make changes to that code.
             | 
             | I've joined quite a few projects after 1/2 years of someone
             | else making the project. And so often it's such an imposing
             | mass of code that basically does sod all. Bad architects
             | who don't understand why they're even using the patterns
             | they are or mid/junior-level coders making projects is
             | basically a recipe for the project just grinding to a halt
             | just when it looks like you're getting near the end.
             | 
             | It's when 1,000s of lines are easily refactored to 100s
             | that you start thinking, how can these people honestly
             | believe they have the ability to lead a project? They are
             | so clearly completely out of their depth it's depressing.
             | 
             | We seem, as an industry, to have a complete inability for
             | management to distinguish genuine senior developers from
             | people who will never be.
        
           | Pxtl wrote:
           | > code organization
           | 
           | It's also the code documentation.
           | 
           | Having documentation that is legible is good, right? And so a
           | reviewer is reasonable to say "this is hard to read" since
           | it's failing at its primary purpose.
        
           | yuliyp wrote:
           | Systems need to be able to handle all kinds of stresses
           | placed on them during their useful life. The runtime
           | bytecode/machine code/config is what deals with the actual
           | running of the system. The code is what deals with the
           | engineers making future modifications to it. The monitoring
           | system deals with being able to allow operators to ensure the
           | system stays up. All of these affect the reliability and
           | performance of the deployed system during its lifetime. All
           | of them are a part of the design of the system.
        
         | ninetyninenine wrote:
         | Well I mean they wrote books about it and one guy had the
         | audacity to call his opinion a "philosophy" even though it's
         | just an arbitrary opinion.
         | 
         | Most of software is about assigning big words and over
         | complicated nomenclature to concepts and these things
         | masquerade as things with deeper meaning when in reality it's
         | just some made up opinion.
         | 
         | Software design is an art. It is not engineering and it is not
         | science. That's why there's so much made up bullshit. The irony
         | is we use "art" to solve engineering problems in programming.
         | It's like ok we don't actually know the most optimal way to
         | program a solution here so we make up bs patterns and
         | philosophies. But then let's give this bs pattern some crazy
         | over complicated name like Scientology or inversion of control
         | and now everyone thinks it's a formal and legitimate scientific
         | concept.
         | 
         | Well cats out of the bag for Scientology. Not yet for a lot of
         | the bs in software. A "philosophy" is the biggest utter
         | bullshit word for this stuff I've ever seen.
        
           | NeutralForest wrote:
           | But there are typical practices we agree are good: using a
           | VCS, writing tests, write comments when needed, separate
           | different level of abstractions, etc. Right? This comes from
           | years of common experience in software.
           | 
           | Over time we get to find patterns, common issues and ways to
           | fix them, etc. It doesn't have to be strict patterns but
           | overall strategies.
           | 
           | If we don't do that then it's just vibes right? Where's the
           | engineering part?
        
             | ninetyninenine wrote:
             | Nothing is fixed in stone. If you have strong typing and
             | program with pure functions and immutability while
             | utilizing union types and matching to the full extent you
             | typically need very few unit tests for your code to work.
             | You just need integration and e2e tests.
             | 
             | I write very little unit tests as my coding style that
             | employs static checks as viciously as possible doesn't
             | necessitate it.
             | 
             | I would say only 30 percent of patterns are good and
             | shared. The other stuff is just artistry and opinion. Like
             | method name length or comments or OOP.
        
               | NeutralForest wrote:
               | I don't really agree, unit test should test behavior,
               | having types of not should not be a defining factor in
               | the coverage.
               | 
               | I don't think patterns as a whole are good but there are
               | known issues and structures to existing problems so
               | boiling it down to art seems reductionist imo.
        
               | ninetyninenine wrote:
               | You don't agree because you likely aren't utilizing
               | static checks to the extent that I do. Like there are no
               | strings or numbers in my code. Everything is operating on
               | strict union type boundaries. The only place where you
               | have unbounded types like strings is on the interface to
               | IO or state.
               | 
               | I can code and not test behavior and have that behavior
               | work reliably without tests. Key word is the unit trst.
               | Typically IO and things that live outside these
               | boundaries need integration tests.
               | 
               | Most of web programming today actually doesn't need much
               | unit testing. You're not doing much processing. The web
               | layer functions as a router and that layer is a meta
               | layer that writes code that executes somewhere else.
               | 
               | Over half the code executes as sql. Integration tests are
               | by far more important.
               | 
               | Boiling it down to an art is not reductionist. It's true.
               | Where is the scientific method in programming? How was a
               | pattern deduced using the scientific method? If it was
               | not deduced using the method then was it created from
               | axioms and logic like math? Is it a theorem?
               | 
               | No. It's all just made up. And we have no quantitative
               | way of verifying why one design is better than another
               | design. That's why software technology often moves
               | horizontally. There's no way to verify the current design
               | was better than the last.
               | 
               | Even both you and I have a disagreement and are at a
               | stalemate. Can you prove your unit testing is superior to
               | my static testing? Not really. Actually tbf static
               | checking is provably better if you don't count the
               | dimension of effort required to use dependent types.
        
               | NeutralForest wrote:
               | That's an interesting approach, I'd like to see an
               | implementation of what you're talking about. What
               | language are you using that has such an expressive type
               | system?
               | 
               | Oh, I agree that there usually isn't a scientific method
               | to programming. I think there could be though. Not for
               | everything of course, some things will always be up to
               | personal taste and interpretation but the cursor could
               | probably be moved with some effort in analyzing existing
               | codebases at scale, doing surveys, internal testing of
               | different approaches in large companies. Something more
               | akin to what you see in social sciences, even if it might
               | be a bad word in some circles!
               | 
               | We probably won't agree but I legitimately enjoy hearing
               | about how people code.
        
               | ninetyninenine wrote:
               | Typescript is capable of dependent typing, union types,
               | exhaustive matching and everything needed to achieve this
               | style of programming. It's just not strict.
               | 
               | The other language is rust. Though it's type system is
               | not as expressive as typescript it is strict meaning
               | nobody can really cheat their way out of it. In general
               | Rust code requires less unit tests then typescript
               | because of this.
               | 
               | The other language is Idris and Haskell. But these
               | languages are rarely used.
               | 
               | This article can shed some insight into what I'm talking
               | about: https://wiki.haskell.org/Why_Haskell_just_works#:~
               | :text=The%...
        
               | NeutralForest wrote:
               | Thanks, I haven't touched Typescript in a while so it
               | might be the occasion for that. When do you feel like you
               | have a handle on the behavior, do you have complex
               | integration tests then?
        
               | yakshaving_jgt wrote:
               | I write a big web application with a fairly type-oriented
               | language, and I still write lots of unit tests. Mostly to
               | do with parsing.
        
               | ninetyninenine wrote:
               | Yeah. That's where it should be. Usually though you don't
               | need much parsing as it's coming in as json or a
               | protobuf. But the interface between IO and your code
               | program is where exceptions and errors can occur. Beyond
               | this boundary your code should be pure and deterministic.
               | 
               | Since you're doing your own parsing rather then using
               | schema validators and existing formats like json, yes
               | your code is doing A LOT of data processing and thus
               | requires a lot of unit tests. Most of the time developers
               | can trust the parsing libraries.
        
               | yakshaving_jgt wrote:
               | What you're describing isn't exactly new territory for
               | me. Maybe you're writing for the room, and not
               | immediately for my benefit.
               | 
               | Parsing is kind of... everywhere. Path piece instances?
               | Parsing. Forms? Parsing. The whole point of smart
               | constructors is parsing. Deserialising from the
               | persistence layer? Parsing. Sure, JSON and Protobuf also,
               | but even when relying on a robust library like aeson, we
               | still write tests. Why wouldn't you? The types you define
               | can be serialised in different ways, and the way you
               | deserialise needs to roundtrip with the way you (or an
               | external system) serialise(s), which also necessitates
               | more tests.
        
               | ninetyninenine wrote:
               | I wouldn't because the deserialization library is tested
               | to death by the library maintainers.
        
               | NeutralForest wrote:
               | I don't really agree, unit test should test behavior,
               | having types or not should not be a defining factor in
               | the coverage.
               | 
               | I don't think patterns as a whole are good but there are
               | known issues and structures to existing problems so
               | boiling it down to art seems reductionist imo.
        
               | globnomulous wrote:
               | Could you give an example where you've used a "static
               | check" where someone else might be likelier to use a unit
               | test? I'm curious.
        
           | coliveira wrote:
           | The issue is that programming is communication. Communication
           | is indeed a form of art. Programming is not just giving
           | instructions to machines, if that was the case we would be
           | happily using binary code. So we have two dimensions, the
           | first one is giving the binary instructions, but the other
           | one is how to make these instructions understandable by
           | humans, including ourselves.
        
             | ninetyninenine wrote:
             | No there are other dimensions to coding. Communication is
             | ONE dimension only.
             | 
             | There is optimization and there is modularity. All 3 of
             | these dimensions are intimately tied and correlated.
        
         | voidhorse wrote:
         | I think it stems from fundamental misunderstandings about what
         | it is one is actually trying to do when writing code.
         | 
         | Coding is about building a _computable model_ of some facet of
         | existence, usually for some business. When it comes to model
         | building, comprehension and communication are paramount.
         | Performance and other considerations are also important but
         | these are arguably accidental features of machines and, in an
         | ideal world, would not actually affect our model.
         | 
         | Similarly, in an ideal world, we wouldn't even need programming
         | languages. We'd be able to devise and explain computational
         | systems in some kind of perfect abstract language and not need
         | to worry about their realization as programs.
         | 
         | I think a lot of these blanket philosophies confuse people by
         | not emphasizing the higher level aspects of the activity
         | enough. Instead people get hung up on particular patterns in
         | particular paradigms/languages and forget that the real goal is
         | to build a system that is comprehensible to the community of
         | maintainers that need to work with it.
        
           | gibibit wrote:
           | It seems that each software design/development system,
           | ideology, and practice has a good reason it was created, and
           | has certain inherent benefits. Each may solve (or at least
           | help with) some common problem.
           | 
           | For instance, abstraction is good and short methods are good
           | to some extent (who wants to read a 2000-line function?), but
           | as John points out in the article, these can be taken too
           | far, where they create new and perhaps worse problems.
           | 
           | It seems there's a pendulum that swings back and forth. We go
           | from big up front design, to Extreme Programming, to a
           | pervasive object-oriented design culture, back to other
           | paradigms.
        
         | mlinhares wrote:
         | Because its easy to be dogmatic, you don't need to think,
         | consider the consequences or drawbacks, you just follow
         | whatever the Supreme Leader told you to do.
         | 
         | Its incredibly simple to just follow whatever someone is
         | telling you to do, sometimes I wish I could live like this so I
         | didn't have to fight with the people that do all the time.
        
         | crabbone wrote:
         | Professionals in other industries don't "just" write books. In
         | a sense that usually the field has several acclaimed authors
         | and they put some solid work into ensuring their books make
         | sense. While there are disagreements in other fields, or some
         | nonsense conventions, the conventional wisdom is usually at
         | least good enough to make you a good professional.
         | 
         | In programming it's the Wild West. Many claims are made based
         | on nothing at all. It's very rare to see any kind of sensible
         | research when it comes to the science part of CS. But following
         | rules makes life easier. Even if rules are bad. That's kind of
         | why conservatism exists as a political idea.
        
         | wglb wrote:
         | Yes, Uncle Bob is certainly capable of being pedantic. A friend
         | of mine, a Smalltalk Consultant, partnered with him for a
         | while. "With Uncle Bob, it's his way or the highway."
         | 
         | His clean code work is certainly pretty dogmatic. As I recall,
         | he says that Java is not object oriented.
         | 
         | But if my memory serves me correctly, his book about C++
         | (Designing Object-Oriented C++ Applications Using the Booch
         | Method) has some excellent parts. His description of the
         | difference between a class and an instance is one of the better
         | ones.
         | 
         | Then there is the famous sudouko puzzle incident, in which a
         | student trying test-driven development can't get the solution.
         | It is a very instructive incident which illustrates the TDD is
         | unlikely to help you solve problems that are beyond incremental
         | changes. Peter Norvig's solution makes that very clear. Uncle
         | Bob does not seem to realize that.
         | 
         | > Who else has had to deal with idiots who froth at the mouth
         | when you exceed an 80 line character margin?
         | 
         | But I admit in my youth, I was pretty dogmatic about languages
         | and development practices, so I've been that guy.
        
           | brianmcc wrote:
           | >> ... TDD is unlikely to help you solve problems that are
           | beyond incremental changes.
           | 
           | Thank you for expressing this niggling problem with TDD.
           | Personally I just cannot use it for "new stuff", I need to
           | explore and create direct with "real" code for anything non-
           | obvious.
        
             | arcanemachiner wrote:
             | I'm more of a DTT man myself: Develop, Then Test.
        
               | brianmcc wrote:
               | +1
               | 
               | I think "code is carefully designed AND has a bunch of
               | decent tests" places a codebase ahead of many tbh, even
               | now, regardless of how it's produced
        
           | switchbak wrote:
           | Wasn't that Ron Jeffries who failed to solve that?
           | 
           | I think that says more about the person at the keyboard and
           | their lack of familiarity with the solution space than
           | anything about TDD per-se. You still need insight and design
           | with TDD, blind incrementalism was never a good idea.
        
             | Crenshaw2 wrote:
             | I agree.
             | 
             | I have used TDD professionally in several development
             | teams. It's useful in the right team. TDD works well when
             | you are not too dogmatic about it. As with everything, you
             | need people in the team that are experienced enough to know
             | when and where. I think the same is true for any tool,
             | coding standard, best practice or what have you. You have
             | to know when to deviate.
             | 
             | I've also held entry courses at university level teaching
             | introductory programming. I believe that TDD can be a good
             | tool teaching programming. Students tend to sit down and
             | write a complete program and then start debugging. TDD
             | teaches them to write small bits at a time and test as they
             | go.
        
             | wglb wrote:
             | What UB's description of how to do TDD does not suggest
             | that there are problems that require a different level of
             | thinking and TDD as he describes, does not account for
             | that.
        
           | zamalek wrote:
           | > Java is not object oriented.
           | 
           | Java _technically_ isn 't OO in the strictest sense
           | (Smalltalk, Ruby). It is OO in the modern sense (where modern
           | >= 1980s, C++). Though I am not sure if this is what Bob is
           | referring to - I don't have any respect for the man or his
           | ideas, so my biased guess is his definition of OO is shared
           | only between him and his fans.
        
           | fuzztester wrote:
           | >But if my memory serves me correctly, his book about C++
           | (Designing Object-Oriented C++ Applications Using the Booch
           | Method) has some excellent parts.
           | 
           | If _my_ memory serves me correctly, Grady Booch himself had a
           | book with roughly the same title, except that his name would
           | not be in the title, of course, but would be there as the
           | author. I think I read a good amount of it long ago, and
           | liked it.
           | 
           | Edit: I googled, the book is mentioned here under the section
           | Booch method :
           | 
           | https://en.m.wikipedia.org/wiki/Grady_Booch
        
           | tqwhite wrote:
           | Bob's had a long life with too much success. He really
           | believes in himself. But, I have to say that the other guy
           | was aggressive and bad even though I am more inclined to
           | agree with him. He willfully misrepresented Bob's ideas. I
           | thought he presented more misguided certainty than Bob. No
           | Bueno.
        
             | usefulcat wrote:
             | The "other guy" is John Ousterhout, author of the Tcl
             | scripting language.
             | 
             | Although I can see why you might consider him more
             | "aggressive", I personally think it matters much more that
             | he was, in general, far more descriptive of his reasoning.
             | 
             | Merely having an opinion is the easy part; being able to
             | clearly articulate the reason(s) _why_ one has a particular
             | opinion is far more important, especially in this kind of
             | conversation, and I in that regard I repeatedly found UB
             | lacking.
        
         | iterateoften wrote:
         | The worst engineer I worked with was one who believed if he
         | read it in a book, that opinion trumped anything else. Once he
         | got so flustered he started yelling "come back to the
         | discussion when you've read 13 books on this topic like me!"
         | And it was something super mundane like how to organize config
         | files or something.
         | 
         | Made every engineering planning session a pain in the ass.
        
         | renewedrebecca wrote:
         | The place I used to work at had a "architect" who would for any
         | question to a decision he made would refer to whatever it was
         | as a "best practice."
         | 
         | Was often quite wrong and always infuriating.
        
         | dominicrose wrote:
         | Square people are never going to agree with cool people. You
         | can be cool and code some monstruosity or you can be square and
         | say "we have to rebuild this entire project from scratch"
         | everytime you see a long method.
        
         | trevor-e wrote:
         | I cringe thinking about PR comments I left early in my career.
         | 
         | "akshually this should try to follow more SOLID principles"
         | 
         | But, coming from a formal engineering background, I thought
         | this is what it meant to be a professional software engineer.
         | Little did I know these "principles" were just the musings of a
         | consultant lol. Turns out most folks have good intentions and
         | want a standardized way to write code, but for some reason it
         | always results in code that looks like the Enterprise FizzBuzz
         | meme repo.
        
           | mp05 wrote:
           | The mark of a good engineer is knowing when this sort of
           | handwaving is actually meaningful and helpful. Formality for
           | its own sake is anti-pattern, but who am I telling?
        
           | sunrunner wrote:
           | For some reason in software there seems to be an incredibly
           | large space for non-evidence based thinking and belief
           | systems.
           | 
           | I wonder if that's because in a lot of cases (depending on
           | the domain) the space of possible valid/working solutions is
           | near infinite, and if you don't have hard requirements that
           | are backed up by measurements you're free to concieve of any
           | valid system structure and justify it as 'better' without
           | that ever being something that can be observed and measured.
        
             | Aurornis wrote:
             | > For some reason in software there seems to be an
             | incredibly large space for non-evidence based thinking and
             | belief systems.
             | 
             | The secondary problem is that book authors have become
             | extremely good at inventing pseudo-evidence to support
             | their claims. It most commonly takes the form of "I talked
             | to X companies with Y total number of employees over Z
             | years and therefore I know what works best".
             | 
             | If you cut out all of the grandstanding, it's nothing more
             | than "just trust me" but in a world of social proof it
             | sounds like it's undeniable.
        
               | sunrunner wrote:
               | > a world of social proof
               | 
               | Which results in the idea of 'good practice', 'best
               | practice' and 'bad practice', and nobody wants to be seen
               | as the person doing things that are considered bad
               | practice, because that would imply that you're a bad
               | developer.
               | 
               | And I almost always hesitate to use the term 'engineer'
               | because as far as I know engineering is considered to be
               | a practice/process that uses measurements and results to
               | drive decision-making, unlike various areas in software.
               | Can you imagine if the same kind of thinking was applied
               | in civil engineering? "This new material has a lot of
               | stars on GitHub and everyone is saying the old materials
               | are bad practice."*
               | 
               | * Which is a thing of course (see: Asbestos) but only in
               | the places with measurable observable outputs.
        
         | jsbg wrote:
         | > Who else has had to deal with idiots who froth at the mouth
         | when you exceed an 80 line character margin?
         | 
         | Not once in my 11 year career. But almost every codebase I've
         | worked on has had debilitating maintainability issues because
         | the only principle other engineers seemed to follow was DRY, at
         | the sacrifice of every principle in SOLID.
        
           | nuancebydefault wrote:
           | Most code that i clean up is a lot easier to maintain after
           | making it a lot DRYer.
           | 
           | The point is not about being DRY, on itself, though. The
           | point is that the code then has better abstractions which are
           | easy to reason about.
           | 
           | UB seems to take abstractions a lot too far, replacing e.g. 2
           | lines of very clear code with some cleartotals abstraction.
        
             | TeMPOraL wrote:
             | clearTotals() arguably made more sense than other
             | "abstractions", on the grounds that if you have more than
             | one piece of state to reset/initialize, you want to
             | centralize the knowledge of _which variables_ must be set
             | together - otherwise it 's too easy to add another piece of
             | state and forget to set it everywhere it should be.
             | 
             | Of course, a method is but one of several ways you could
             | capture that information, and not always the best one.
        
             | jsbg wrote:
             | DRY is about ensuring that the same code doesn't have to
             | change in two places because the engineer changing it in
             | one place might not know that. But so many applications of
             | DRY mindlessly violate the single responsibility principle
             | and create coupling where there shouldn't be.
        
         | Aurornis wrote:
         | > It still blows my mind how dogmatic some people can be about
         | things like this. I don't understand why anyone takes these
         | things as gospel.
         | 
         | I love reading books for different perspectives.
         | 
         | However, I've come to despise people who read books and then
         | try to lord their book knowledge over others. These are the
         | people who think that they have the upper hand in every
         | situation because they read some books. They almost always
         | assume you haven't read them. If you point out that you have
         | also read them, they switch the subject to another set of books
         | they read because they don't like when someone tries to
         | undermine their book knowledge superiority.
         | 
         | It's even worse when the person reads books outside of their
         | domain and tries to import that book knowledge into the
         | workplace. The absolute worst manager I had was a guy who read
         | a lot of pop-psychology books and then tried to psychoanalyze
         | each of us according to those books.
        
         | DeathArrow wrote:
         | For many C#, Java and C++ engineers Uncle Bob is their savior
         | and GoF are the apostles.
         | 
         | Everything should follow SOLID and clean principles and be
         | implemented using design patterns.
        
           | jayd16 wrote:
           | Game devs out here catching strays.
        
             | monksy wrote:
             | Good. The code I've seen from Game devs, the bad practices
             | justified, and the ego is excessive.
        
           | neonsunset wrote:
           | Which is unfortunate as there are no (legitimate) reasons to
           | write C#, a multi-paradigm language, like this.
        
           | progmetaldev wrote:
           | One of the best things I could do for myself is to go back in
           | time and tell my younger self not to care so much about the
           | "right" design pattern, or the perfectly DRY way to represent
           | a piece of code. I was definitely my worst enemy for a long
           | time, because I thought SOLID and the GoF design patterns
           | were more important than writing code that is easy to
           | understand without hopping across multiple files in case one
           | day in the future your system needed to do something totally
           | different with a new database or filesystem, etc. I started
           | to look for places to add design patterns, rather than
           | letting them develop naturally. Most of the software I built
           | had no need for such heavy abstraction and complexity, and
           | I've only ever had to switch database systems twice ever in
           | 20 years, and the abstraction did not help reduce time or
           | complexity all that much in the end. It definitely wasn't
           | worth the up front planning compared to just rewriting the
           | sections that directly handled the database.
           | 
           | Maybe it's a right of passage to burn yourself badly enough
           | over-architected solutions, where you finally start to
           | understand you don't need all the complexity. Write the code
           | for humans, as simple as you can. Keep large performance
           | issues in mind, but only code around them when they become a
           | problem or are extremely obvious. If anything, it's helped me
           | to steer junior developers away from complex code, while
           | encouraging them to try it out in their own time. Go ahead
           | and figure things out on your own, but let's not do it on a
           | shared codebase, please?
        
         | soulofmischief wrote:
         | On my Macbook Pro M2, having a browser window on one half of
         | the screen, and my IDE on the other, with a file tree viewer
         | pane and another pane for my LLM tools, a terminal pane at the
         | bottom... I've never been more pressed for real estate for my
         | actual code editing pane. Even 80 chars has me scrolling
         | horizontally. Secondary monitors help but not when you
         | frequently work away from your desk.
        
           | ajross wrote:
           | Coding on a laptop, even a name-drop-tier status shibboleth,
           | is most of your problem. You write code on a 15" screen when
           | you must for physical/location reasons. You shouldn't ever
           | choose to do it or design your workflow around that
           | constraint.
           | 
           | A 42" 4k TV (got it for $2-300 at the start of the pandemic)
           | gives me four 80-90 column text windows on a mid-tier
           | chromebook. You could not pay me enough to do that same work
           | on a laptop, even a $4k MBP.
           | 
           | (But yes, even with lots of real estate 80 columns is still a
           | net win)
        
             | soulofmischief wrote:
             | I have a 120" 4K monitor at home, and a 40" 2K. However,
             | that entirely misses the point of my comment, which is that
             | I am frequently away from my desk while working. I'm not
             | sure what point you were trying to make.
        
               | cluckindan wrote:
               | Invest in the Vision Pro. It will change your life.
        
               | soulofmischief wrote:
               | I was also looking at the XREAL Air 2 Ultra, seems more
               | practical for travel, but the idea of an ultrawide screen
               | sounds really nice. I might take your advice.
        
         | 0x20cowboy wrote:
         | This is just how junior and intermediate devs behave. It's like
         | a goth phase or something.
         | 
         | It goes along with being into BJJ, chess, vim, keto, linters,
         | and "the dominance hierarchy".
         | 
         | It's annoying, but most everyone went through it. If you didn't
         | know better, how could they?
        
       | kragen wrote:
       | Crucial context here: Ousterhout is one of the great programmers
       | who built the free software world we live in today, and Uncle Bob
       | is a faker. Ousterhout is not without his problems (Stallman
       | famously called him a "parasite" on the free software community,
       | as well as fervently disagreeing with his technical taste) but
       | he's written truly world-changing software. By contrast, Uncle
       | Bob is a windbag book author who has never managed to write any
       | software worth using, to my knowledge.
       | 
       | Ousterhout to Uncle Bob:
       | 
       | > _maybe you were surprised that it is hard to understand, but I
       | am not. Said another way, if you are unable to predict whether
       | your code will be easy to understand, there are problems with
       | your design methodology._
       | 
       | This debate is full of treasures like this. What a brilliantly
       | clear and understated way to expose charlatanism!
       | 
       | What is this "world-changing software" I'm saying Ousterhout has
       | shipped? Tcl. (Hold on, now, don't downvote just yet.) Tcl has
       | been a crucial enabling technology for EDA and automated
       | regression testing since literally the 01980s. Probably every
       | VLSI chip in the computer you're reading this on was designed,
       | verified, and tested with workflows involving unholy amounts of
       | Tcl. GCC's test suite is also Tcl. Still.
       | 
       | Automated testing in the 01980s? Yes. It's true that automated
       | testing wasn't very prevalent in the software world until the
       | Agile guys (Uncle Bob and his less incompetent compatriots)
       | popularized it around the turn of the century, but EEs and
       | compiler engineers have been pervasively automating testing a lot
       | longer than that, and Tcl was for a long time the least awful
       | option, believe it or not. And that was John Ousterhout's doing.
       | 
       | Do you know what the SPICE developers did to make SPICE
       | scriptable, before there was Tcl? They linked csh into it.
       | Motherfucking _csh_. If you 've never tried to maintain a large
       | script in csh, you do not know the meaning of suffering.
       | 
       | Good programmers write good software; bad programmers write bad
       | software, or no software. Ousterhout has written one of the few
       | pieces of software that can be called great. (In its historical
       | context. In 01978 csh was great software too.) What software has
       | Uncle Bob written?
       | 
       | Listening to Uncle Bob's programming advice over Ousterhout's
       | would be like listening to your middle-school English teacher's
       | writing advice instead of Stephen King's. It's not that King
       | could never give you worse advice, but if you need your English
       | teacher's advice, generally your judgment will not be good enough
       | to distinguish the rare occasions King gets it wrong.
        
         | WillAdams wrote:
         | Curious what Stallman has to say about Robert C. Martin ---
         | looked, but couldn't find anything....
        
           | kragen wrote:
           | Not about Martin. About Ousterhout. 27-30 years ago.
        
             | WillAdams wrote:
             | Right, I was curious if _in addition to_ that well-known
             | comment there was an evaluation by Stallman of Bob Martin
             | extant.
        
               | kragen wrote:
               | Unlikely. He mostly confines himself to commenting on
               | political issues:
               | https://www.stallman.org/archives/2024-nov-feb.html
        
         | cmacleod4 wrote:
         | I'ma big Tcl fan, but Ousterhout has created many other
         | important things - see
         | https://en.wikipedia.org/wiki/John_Ousterhout .
        
       | okaleniuk wrote:
       | It's sad that we demoted the field from engineering to
       | philosophy. But it is what it is.
       | 
       | Next step - fashion and belief.
        
         | WillAdams wrote:
         | It's an improvement over demagoguery and blind rule-following.
         | 
         | Moreover, the book argues for engineering principles (in pretty
         | much all possible senses of that phrase).
        
           | okaleniuk wrote:
           | Sure!
           | 
           | I'm not saying that philosophy is bad. Maybe making software
           | just never meant to become an engineering discipline. I mean
           | making clothes, laws, and music isn't. And it's fine.
           | 
           | But engineering does imply some rule-following.
        
         | floydnoel wrote:
         | philosophy is the basis of reason, math, and science. it's sad
         | that "engineers" don't understand it or it's import.
        
           | okaleniuk wrote:
           | Engineers believe in definitions. By definition, philosophy
           | is not a scientific discipline, because as soon as a
           | discipline becomes scientific it... stops being philosophy.
           | 
           | As Alexander Pyatigorsky famously wrote, "the value of
           | philosophy is in that nobody needs it".
        
       | cjfd wrote:
       | PDSD is correct on length of methods. The methods given in an
       | example in CC are ridiculously short. CC is more correct on
       | comments than PDSD. Especially mandating comments in certain
       | places leads to very low quality and, frankly, utterly disgusting
       | comments point out, helpfully that the 'get_height' method 'gets
       | the height'. CC is more correct on TDD than PDSD. The noticed
       | danger of just focussing on implementation details over the
       | structure of the API is always there but TDD has a refactor step
       | to fix that. The general idea of working in small steps with
       | there being a safe state between every small step is worth its
       | weight in gold.
        
       | samiv wrote:
       | Instead of "Clean Code" I'd really suggest people read either
       | - Code Complete       - The Pragmatic Programmer
       | 
       | https://en.wikipedia.org/wiki/Code_Complete
       | 
       | https://en.wikipedia.org/wiki/The_Pragmatic_Programmer
        
         | kragen wrote:
         | I wouldn't recommend _Code Complete_ today; I think _The
         | Practice of Programming_ covers most of the same material, is
         | much shorter, is much better written, and isn 't tainted by
         | McConnell's later embrace of snake-oil methodologies, some of
         | which made it into the second edition of CC. TPOP didn't exist
         | when CC changed my world.
        
           | bena wrote:
           | It's been a hot minute since I've read Code Complete. I don't
           | have it on hand, but I'm pretty sure it was the second
           | edition as it has the gray cover. And I'm pretty sure I got
           | the second edition closer to when it was published than
           | today.
           | 
           | I remember it being pretty decent back in the day. I can't
           | remember any takes that were too hot in it. Honestly, I can
           | only remember a general sense of satisfaction(?) with the
           | book. If you were to ask me what exactly I took from Code
           | Complete and applied in my job today, I couldn't tell you.
           | 
           | What would you classify as "snake oil" in it? Do they
           | recommend Hungarian notation or something weird?
        
             | kragen wrote:
             | I read some of the more questionable parts of the second
             | edition just now, and while I think there are a lot of
             | things to criticize in it, I suspect that it's just rose-
             | tinted hindsight, or ignorance, that made me not object to
             | them in the first edition; I'm pretty sure most of these
             | problems were already there:
             | 
             | - All the time wasted on the dumb "construction" analogy.
             | 
             | - The total lack of attention to open-source software,
             | possibly because there's no such thing as a freely
             | redistributable cabinet that's extra reliable because your
             | house shares it with the local nuclear reactor, or a rotten
             | floor joist you can't fix without negotiating a source
             | license. (He does discuss _buying_ libraries.) Though this
             | was surely also lacking in the first edition, it was a more
             | forgivable oversight in 01994.
             | 
             | - Very little attention given to automated testing; we
             | don't get to "developer testing" until chapter 22, though
             | there are a few offhand remarks in SS4.4 and SS9.4 about
             | unit testing, with no explanation of what that means.
             | Again, this was a more forgivable oversight in 01994.
             | 
             | - Also, nothing about source control. Understandable in
             | 01994, irresponsible in 02004, unthinkable today.
             | 
             | - Although he pays lip service at the beginning of the book
             | to the independence of project _phases_ and project
             | _activities_ , he often conflates them later, often
             | presuming a quasi-waterfall model (when he isn't outright
             | advocating it), where a requirements-analysis phase is
             | followed by an architecture phase, then a detailed design
             | phase, then a "construction" phase, then a testing phase,
             | and then finally a maintenance phase. This is obviously
             | completely unlike the reality of projects like Microsoft
             | Windows, Emacs, Linux, GCC, and Facebook. When did Facebook
             | mostly move from detailed design to construction? Would it
             | have been a better social-networking website if it had
             | spent a year or two on architecture before beginning
             | "construction"? He does kind of go back and forth on this a
             | lot, though, sometimes advocating more incremental
             | approaches and then contradicting himself a page later.
             | 
             | - Relatedly, he advocates a division of labor where "the
             | architect consumes the requirements; the designer consumes
             | the architecture; and the coder consumes the design."
             | (Traditionally, though he doesn't say this, the QA tester
             | then consumes the code.) This division of labor has been
             | tried many times, and the companies that have tried it have
             | been mostly outcompeted by companies with less
             | dysfunctional divisions of labor; they mostly survive only
             | in niches where they have legally enforceable monopolies,
             | such as DoD cost-plus prime contractors. None of them have
             | been able to produce products of quality comparable to
             | things like Linux, GCC, and Facebook. I think this is the
             | snake-oiliest part of the book.
             | 
             | - _Code Complete_ 's table of "Average Cost of Fixing
             | Defects Based on When They're Introduced and Detected",
             | table 3-1, is convincing, compelling, thoroughly footnoted
             | with decades of literature, and completely made up. See htt
             | ps://softwareengineering.stackexchange.com/questions/1637..
             | . https://web.archive.org/web/20121101231451/http://blog.se
             | cur... https://www.lesswrong.com/posts/4ACmfJkXQxkYacdLt/di
             | seased-d... https://gist.github.com/Morendil/258a523726f187
             | 334168f11fc83.... This made-up data is McConnell's major
             | justification for advocating waterfall-like models. More
             | recent research that investigates the question empirically
             | instead of relying on made-up hearsay finds, by contrast,
             | "We found no evidence for the delayed issue effect; _i.e._
             | , the effort to resolve issues in a later phase was not
             | consistently or substantially greater than when issues were
             | resolved soon after their introduction."
             | https://arxiv.org/pdf/1609.04886
             | https://agilemodeling.com/essays/costofchange.htm
             | https://buttondown.com/hillelwayne/archive/i-ing-hate-
             | scienc....
             | 
             | - The section about "user interface design" is cringe-
             | inducingly bad. He thinks you can design a good user
             | interface up front without having working software ("The
             | user interface is often specified at requirements time. If
             | it isn't, it should be specified in the software
             | architecture,") rather than incrementally responding to
             | usability feedback from people using a working system. It's
             | a very short section, and that in itself is eyebrow-
             | raising; usability is a central concern of most kinds of
             | software, and one of the most challenging aspects of
             | software. Really, almost everything in most software should
             | be driven ultimately by user experience and grounded out in
             | usability testing. Games, websites, browsers, and even
             | compilers live and die on usability. But McConnell treats
             | it as one minor detail among many.
             | 
             | - The section about the "architecture prerequisite" sounds
             | like it was written by IBM mainframe programmers in 01978,
             | then decorated with some OO and WWW jargon. Yes, clearly
             | the architecture should "describe the major files and table
             | designs to be used". That makes sense. Yes, "Input/output
             | (...) is another area that deserves attention in the
             | architecture. The architecture should specify a read-ahead,
             | read-behind, or just-in-time reading scheme." I mean,
             | _seriously_? Note that words like  "client", "server",
             | "tier", "cache", "protocol", "network", "message", "queue",
             | and even "process" are completely missing here. It's not
             | that he uses different terms for them; he just doesn't talk
             | about them at all, using any words.
             | 
             | - He tries to discuss "fault tolerance" with a totally
             | nonsensical example "the square root of a number",
             | necessarily making complete hash of the topic as a result.
             | He doesn't mention _any_ of the techniques that actually
             | work for achieving fault-tolerance, such as statelessness,
             | idempotence, the end-to-end principle, transactions,
             | journaling, fail-stopness, checksums, disk mirroring,
             | hardware trimodular redundancy, watchdog timers, ECC,
             | anomaly detection, network timeouts, monitoring, alarms,
             | etc. The only exception is that he sort of mentions
             | granular restarts. I 'm restricting myself to techniques
             | that were well-known when he wrote the first edition of the
             | book here, excluding things like Paxos, eventual
             | consistency, and Merkle graphs.
             | 
             | - There are a lot of cases where he repeats something he's
             | heard that he evidently doesn't understand. The muddled
             | attempt to explain fault tolerance above is one example,
             | but we could also mention, for example, his attempt in
             | SS4.1 to describe Fortran programmers writing Fortran in
             | C++, which completely misses the actual major difficulty
             | (it's mostly about structuring the data as arrays, not the
             | control flow), or his remark, "Assembler is regarded as the
             | second-generation language," devoid of the historical
             | context to provide any meaning to it.
             | 
             | - One thing that I think is actually new in the second
             | edition is its presumption that all software is object-
             | oriented (despite paying lip service to the fact that
             | Visual Basic [6] was the most popular language among
             | professional programmers, many people were still
             | programming in Ada and assembly and Cobol and C and
             | Fortran, etc.) and that looks a bit snake-oilier from our
             | perspective now than it did at the time. I think OO is a
             | useful approach to software design, but if I'm writing a
             | generic tutorial on how to design a program, I wouldn't
             | have a step in it called "Level 3: Division into Classes"
             | as McConnell does in SS5.2, because that makes my book
             | completely inapplicable to programming in C, Go, Fortran,
             | Rust, Racket, VB6, or Clojure, and inapplicable to much of
             | what people do in Python, PHP, JS, Octave, and R. The snake
             | oil here is not object-orientation but a totalizing
             | ideology that everything _must_ be OO; the Chapter 6
             | introduction says,  "In the twenty-first century,
             | programmers think about programming in terms of classes.".
             | The way I remember it, the first edition didn't have this
             | problem.
             | 
             | - This totalizing OO outlook is somewhat exacerbated by the
             | fact that he doesn't really understand object orientation
             | at all, so he gives a lot of bad advice, like, "A large
             | percentage of routines in object-oriented programs will be
             | accessor routines, which will be very short," SS7.4. His
             | whole chapter 6 is about designing classes, but he never
             | mentions the actual core concept of object-orientation,
             | which is polymorphic message sends, presumably because
             | although he knows they exist, he isn't really comfortable
             | with them and doesn't understand how central they are to
             | the OO worldview. Instead he treats classes as a newfangled
             | synonym for CLU's "clusters" or Ada "packages". Much of the
             | chapter is devoted to workarounds for shortcomings of C++.
             | This isn't really "snake oil," just incompetence.
             | 
             | There's still much material in the book that's solid, and
             | lots of references to good information, but it's mixed with
             | a lot of serious misinformation, misleading analogies, and
             | embarrassing incompetence. And it's a slog to get through
             | so much verbiage. But it's certainly better than _Clean
             | Code_. Still, now that _The Practice of Programming_ , _The
             | Pragmatic Programmer_ , and _A Philosophy of Software
             | Design_ are out, I think there 's no longer any reason to
             | recommend _Code Complete_.
        
         | mrkeen wrote:
         | I read Clean Code and don't remember a single thing from it. To
         | be fair it was a while ago.
         | 
         | But the SOLID and Clean Architecture principles inform me
         | almost daily.
        
       | donatj wrote:
       | I have worked with a couple of people over the years who instead
       | of breaking functions out when something would say make sense to
       | be reused or made some sort of logical sense as a unit, instead
       | seemingly just bundle lines whose only real relationship was that
       | they happened to be near each other when they decided to
       | "refactor".
       | 
       | Having read Clean Code back in college as it was assigned
       | reading, it was absolutely the vibe I got from Uncle Bob
       | generally. See any number of lines at the same indentation level,
       | select them, extract method, name it vaguely for some part of
       | what it does, repeat.
       | 
       | I honestly think that it comes from this type of school of
       | thought that a function should be X lines rather than a function
       | achieving a _function_. Thinking about this now, it 's sort of
       | the difference between "subroutines" and "functions".
       | 
       | Working on their code, I thank god for modern IDEs ability to
       | inline. I often go through and restructure the code just to
       | understand the full scope of what it's doing, before restoring
       | what I can of the original to make my changes as minimal as
       | possible.
        
         | zelos wrote:
         | The warning sign I see when methods are split too much is that
         | the method boundaries start to get messy: methods take too many
         | arguments, or state is saved into confusingly named class
         | members, or you end up returning some struct containing a grab
         | bag of unrelated values.
        
           | donatj wrote:
           | All of this all the time
        
         | kraftman wrote:
         | It's been a long time since I've read the book but I took it to
         | be less 'cut the function at X lines' and more 'long functions
         | tend to be doing too many things at a time'. I think if you're
         | able to give a good name to some sub section of a function,
         | it's a good sign that it can be extracted out. At that point,
         | you shouldnt need to look at the functions implementation
         | unless its the specific function that you want to modify,
         | because its name and arguments should be enough to know what it
         | does and that you don't need to touch it.
         | 
         | Are we talking about the same thing and you'd still find that
         | hard to understand?
        
       | ArchieMaclean wrote:
       | My take on the prime example:                   import itertools
       | def generate_n_primes(n):             """             Generate n
       | prime numbers using a modified Sieve of Eratosthenes.
       | The algorithm keeps track of a list of primes found so far,
       | and a corresponding list of 'multiples', where multiples[i] is a
       | multiple of primes[i],             (multiples[i] is initially set
       | to be primes[i]**2, see the optimisations section below).
       | The main loop iterates over every integer k until enough primes
       | have been found,             with the following steps:
       | - For each prime found so far             - While the
       | corresponding multiple is smaller than k, increase it by steps of
       | the prime             - If the multiple is now the same as k,
       | then k is divisible by the prime -                 hence k is
       | composite, ignore it.             - If, for EVERY prime, the
       | multiple is greater than k, then k isn't divisible by any
       | of the primes found so far. Hence we can add it to the prime list
       | and multiple list!                      There are a few
       | optimisations that can be done:             - We can insert 2
       | into primes at the start, and only iterate over every odd k from
       | there on             - When we're increasing the multiple, we can
       | now increase by 2*prime instead of 1*prime,             so that
       | we skip over even numbers, since we are now only considering odd
       | k             - When we find a prime p, we add it to the prime
       | and multiple list. However, we can instead add             its
       | square to the multiple list, since for any number between p and
       | p**2, if it's             divisible by p then it must be
       | divisible by another prime k < p             (i.e. it will be
       | caught by an earlier prime in the list)             """
       | # Insert 2 into primes/multiples             primes = [2]
       | multiples = [4]                      # Iterate over odd numbers
       | starting at 3             for k in itertools.count(3, 2):
       | # If we've found enough primes, return!                 if
       | len(primes) >= n:                     return primes
       | # For each prime found so far                 for i in
       | range(len(primes)):                     # Increase its
       | corresponding multiple in steps of 2*prime until it's >= k
       | while multiples[i] < k:                         multiples[i] += 2
       | * primes[i]                              # If its corresponding
       | multiple == k then k is divisible by the prime
       | if multiples[i] == k:                         break
       | else:                     # If k wasn't divisible by any prime,
       | add it to the primes/multiples list
       | primes.append(k)                     multiples.append(k ** 2)
       | return primes
       | 
       | Some might find the docstring as well as comments too much - I
       | find the comments help relate the code to the docstring. Open to
       | suggestions!
        
       | aswerty wrote:
       | While I enjoyed the discussion as an exercise in stripping back
       | positions to underlying principles. I find it a great irony that
       | the overarching reason why they diverge on what is "good
       | practice" is not discussed.
       | 
       | John sounds like he is about to start building a new type of
       | database, and Bob sounds like he's knee deep in a 20 year old
       | code base for a logistics company. Both of their positions are
       | reasonable, and both optimized for specific contexts.
       | 
       | I found Bob's responses more measured (which I value a lot), with
       | John's at times being more compelling. I do agree that over-
       | composition is a real problem that Bob is on the wrong side of
       | the line on. But to be fair, Bob and Clean Code comes from a time
       | where it was the opposite and his position on this feels like a
       | philosophy that has an over-correction (albeit - not necessarily
       | a flaw) at it's core.
        
       | ptx wrote:
       | UB says at one point:
       | 
       | > _Would that we had such a crystal ball_
       | 
       | And then it seems like he actually found his crystal ball,
       | because in the very next question he refers to things that have
       | not yet occurred in the conversation:
       | 
       | > _interpreting your rewrite (below)_
       | 
       | And later:
       | 
       | > _In your solution, which we are soon to see below_
       | 
       | This makes it somewhat confusing to read, with answers being
       | based on counterpoints that will only have been made in the
       | future. (Which, I suppose, is similar to the problem Ousterhout
       | has with UB's PrimeGenerator example.)
        
       | bonsaiKiller wrote:
       | There's obviously a balance. Having worked in both environments,
       | I tend to appreciate the code of someone who at least read the
       | books, but treats it as suggestion rather than gospel. Contrast
       | to someone who never read the books, has no clue what's "good"
       | and hacks everything.
       | 
       | On the one hand, the books are popular because a lot of people
       | reading them think it makes a good point, and share that view. On
       | the other hand, just because something is popular doesn't make it
       | right! I think this is where AI gets so much wrong. GIGO! If you
       | base all your code on whatever is most common, are you really
       | really sure that common pattern is really the best? AI, and these
       | book evangelist, often have no clue. Just parroting others.
       | 
       | I'd rather deal with "principles" as opposed to "rules" every
       | time. Glean the principles from the books, and at least try to
       | write clean code!
        
       | bob1029 wrote:
       | I'm currently dealing with one of those codebases representative
       | of the consequences of blindly following "Clean Code", et. al.
       | 
       | My experience has taught me that you never want to be the first
       | person to recommend a rewrite. Since I am a mere contractor on
       | this one, I am strongly inclined to let it unwind on its own.
       | There seems to be a lot of ego embedded in those pointless data
       | access layer wrappers. I'd hate to get on someone's bad side
       | right now. The market is quite rarified.
        
         | bluGill wrote:
         | Rewrite is only useful it you get something else that you can't
         | get otherwise. Mixing Rust and C++ in a project is hard but
         | doable - odds are if you try it you will find enough "friction"
         | that eventually it will be worth rewriting to get rid of one.
        
       | sam_bishop wrote:
       | One of my beefs with Clean Code is its name.
       | 
       | There is no objective measure of code cleanliness. So if "clean
       | code" is your goal, then you have no meaningful criteria to
       | evaluate alternatives. (Including those pitched by Bob Martin.)
       | 
       | It gets worse, though. There's a subconscious element that causes
       | even more trouble. It's obviously a good thing to write "clean
       | code", right? (Who's going to argue otherwise?) And to do
       | otherwise would be a moral failing.
       | 
       | The foundation on which "Uncle Bob" tries to build is rotten from
       | the get-go. But it's a perfect recipe for dogmatism.
        
         | bpicolo wrote:
         | Honestly that kind of makes the word "clean" seem like a good
         | fit to me. I can't say that measuring the cleanliness of my
         | house is objective.
        
       | jjice wrote:
       | Lots of negative comments about Uncle Bob in this thread. I
       | personally didn't like Clean Code and really enjoyed A Philosophy
       | of Software Design, but I do think that some of his other books
       | are really solid.
       | 
       | I accept that non-fiction books on anything will oversell the
       | value of their way, and try to take what I can at a more moderate
       | level. Through that lens, Clean Code didn't give me much, but
       | Clean Architecture did. The Clean Coder is also an interesting
       | read on professionalism in software, and Clean Agile is an
       | interesting read on Agile roots. I don't know anyone that
       | practices "true" agile (nor do I care to do so myself), but there
       | are some really solid ideas in there.
       | 
       | I get that Clean Code kind of had a cult-like following in that
       | people followed it blindly, but damn some of these comments are
       | just rude about Uncle Bob. I still think he's a pretty good
       | author and has given me some advice through his other books that
       | helped me a lot as a fresh faced dev.
        
         | mangodrunk wrote:
         | Uncle Bob has been a horrible influence on our industry, and
         | we're expressing that. He has not actually worked on anything
         | but yet he's been able to make some money selling his
         | inexperienced opinions.
        
       | Hasu wrote:
       | > I bemoan the fact that we must sometimes use a human language
       | instead of a programming language. Human languages are imprecise
       | and full of ambiguities. Using a human language to describe
       | something as precise as a program is very hard, and fraught with
       | many opportunities for error and inadvertent misinformation.
       | 
       | This quote from Uncle Bob is shameful, considering that he has
       | made 100% of his career on writing _English_ , not code.
        
         | WillAdams wrote:
         | An interesting contrast to it is Ousterhout's observation:
         | 
         | >If you can visualize a system, you can probably implement it
         | in a
         | 
         | >computer program.... This means that the greatest limitation
         | in writing
         | 
         | >software is our ability to understand the systems we are
         | creating.
         | 
         | Though interestingly it is in marked contrast to a different
         | statement in the "Software Design Book" Google mailing list:
         | 
         | >John Ousterhout, Aug 21, 2018, 12:30:15 PM
         | 
         | >I've never felt that graphs are a particularly useful way of
         | describing software structure.
         | 
         | >The interactions between classes end up so complicated that
         | the graph becomes an unreadable mess.
         | 
         | >Also, I'm not sure that the complexity of a graph
         | representation of software correlates with its
         | 
         | >practical complexity (the graph representation might look very
         | complicated, but the software might
         | 
         | >still be pretty easy to maintain).
         | 
         | and I'd be interested if someone knows of a
         | text/video/interview which resolves that twain, or what sort of
         | visualization is advocated for/recommended.
        
           | Izkata wrote:
           | Structure graphs are rarely useful for me, but visualizing
           | the data flow is how I think about code in general. Sometimes
           | it's graph-like, but more wishy-washy and I'm only holding
           | the relevant parts for the task at hand in my head rather
           | than everything.
        
       | loganmhb wrote:
       | Plenty of people are ragging (justifiably) on Clean Code, but I
       | really admire by contrast Ousterhout's commitment to balanced
       | principles and in particular learning from non-trivial examples.
       | Philosophy of Software Design is a great and thought-provoking
       | read.
        
         | cowboylowrez wrote:
         | Philosophy of Software Design seemed more pragmatic to me.
        
       | 0xbadcafebee wrote:
       | > For me, the fundamental goal of software design is to make it
       | easy to understand and modify the system. I use the term
       | "complexity" to refer to things that make it hard to understand
       | and modify a system.
       | 
       | This explains everything that's wrong with modern software.
       | 
       | When you design a Formula 1 race car engine, the purpose of
       | engine design is not to "make the engine easier to modify". It's
       | to win races. And that depends on the race - a funny car engine,
       | a formula 1 engine, a LeMans engine, Nascar engine, etc, are all
       | different because the races are different.
       | 
       | Another example: when you design a building, the goal isn't to
       | make it easier to understand the building. The goal is to meet
       | the requirements of the building, its uses, requirements,
       | environment, etc. Sometimes a better building is just more
       | complicated, and making the architect or builders' jobs easier,
       | while nice, isn't the goal.
       | 
       | Some things aren't supposed to be easy to understand, because
       | ease of understanding is not the goal of the thing. Focus on the
       | real goal of the thing, and achieving that; don't get distracted
       | by ancillary goals.
        
         | kraftman wrote:
         | Most people aren't building Formula 1 cars. Buildings are a
         | better analogy: they are designed to be maintained. You can
         | replace a door handle without replacing the door or the wall,
         | you can turn off the power to different sections to do repairs.
         | Dangerous or complex parts are labelled, moved into their own
         | rooms or cupboards, and locked.
        
         | allemagne wrote:
         | A genius architect/Formula 1 engineer can design a
         | building/engine that fits all the requirements astonishingly
         | perfectly, but if the builders have difficulties understanding
         | it, or later contractors can't figure out how to maintain or
         | fix anything, then it's only a perfect design in theory and an
         | awful design in reality. It's not a nice-to-have to make
         | people's lives a little easier, it defines the success of the
         | project. The genius architect/engineer can insist that the
         | complex design reflects the underlying domain as much as they
         | want but at some point they will have to back that up to
         | someone else who isn't a genius.
         | 
         | Obviously, writing code such that a first year comp sci student
         | can understand what's happening and can start contributing
         | immediately is absurd, but at the same time nobody builds
         | anything in a vacuum. There's a certain legibility required
         | within any context you're designing something for.
        
         | kragen wrote:
         | Software is unusual in that it's never finished. This makes
         | ease of modification a critical quality of software in a way
         | that it isn't for Formula 1 race car engines or most buildings.
         | 
         | Ease of modification _was_ one of the top priorities in the
         | design of the Model T Ford, because cars break down and must be
         | repaired, and a car that is difficult or impossible to repair
         | will cost its owner large sums of money. Software doesn 't
         | break down (though online services do) but for other reasons
         | modification is a high priority.
         | 
         | Perhaps short-lived buildings don't need to be easy to modify,
         | especially if the architects have a very good understanding of
         | the needs of the users over their lifetimes. Often that is not
         | the case, though, and Christopher Alexander was famous in large
         | part because much of his career was devoted to figuring out how
         | to enable inhabitants of buildings to modify them more easily,
         | so that their needs would eventually be met even if the
         | architects guessed wrong decades in the past. Centuries-old
         | stone farmhouses exist, too, and ease of modification is
         | crucial for them; if they cannot be modified they cease to
         | function in only a century or two at most.
         | 
         | Whatever the goal of your software, it is crucial for the
         | people who are modifying it over time to achieve that goal to
         | be able to understand it.
        
       | jpitz wrote:
       | "Do One Thing" is to me maybe best understood in the context of
       | the Single Layer Of Abstraction Principal - it has helped me
       | numerous times to be very intentional about following SLAP in
       | complex code, and Do One Thing seems to fall very naturally out
       | of it.
        
       | nadam wrote:
       | I was just thinking about what AI assisted coding brings to the
       | design discussion, especially as AI become more and more powerful
       | and we rely on it more and more. You still want to make things
       | modular and easy to understand so that AI understands it easily
       | and the needed info to modify a module can fit in a relatively
       | small context window, but the difference is that it is very easy
       | to make large scale measurement about which code style is
       | understood better by an LLM, so maybe some of these debates will
       | be decided relatively objectively!
       | 
       | For the topic: the discussed topics are relatively trivial
       | surface level stuff, mostly I agree with POSD, but these will be
       | handled by AI anyway. I guess humans will use the spare brain
       | capacity to deal with the real deep design questions (for a
       | while).
        
       | zzzeek wrote:
       | I've been programming since the early 80s and have never seen
       | real world, production code that was done in so-called "clean
       | code" style
        
       | spacechild1 wrote:
       | IMO the "PrimeGenerator" example from Clean Code is horrendous
       | and completely unreadable! This would be so much better as a
       | single method/function with a few interspersed comments that
       | explain the algorithm. I mean, just look at this abomination:
       | private static boolean       isMultipleOfNthPrimeFactor(int
       | candidate, int n) {         return candidate ==
       | smallestOddNthMultipleNotLessThanCandidate(candidate, n);       }
       | 
       | Not only is the method itself completely pointless, it also
       | happens to have side effects! Who would expect this from the
       | method name? So much for self-documenting code... Ousterhout
       | rightfully calls him out on this bullshit.
       | 
       | In fact, Ousterhout makes such great points that I really want to
       | read his book. Conversely, I'm now even less inclined to read
       | Clean Code.
        
         | spacechild1 wrote:
         | > This would be so much better as a single method/function with
         | a few interspersed comments that explain the algorithm.
         | 
         | I haven't read the whole article when I wrote that comment.
         | Turns out that Ousterhout provides a rewritten version of
         | "PrimeGenerator" that does exactly this. At least UB concedes
         | that this version is indeed much better.
        
       | pcblues wrote:
       | On reflection, my attitude to books like these indicated where I
       | was in my understanding of programming. They used to be useful
       | life-buoys that one clung to for dear life early in one's career
       | in a fast-moving and often-changing industry. Then they become an
       | interesting side-note reminding one of what they clung to as the
       | good precepts that served them well stand out from the rest of
       | the books. And finally they become unnecessary and seemingly
       | dogmatic when one has become adept at swimming. In other words,
       | essential reading depending on where you find yourself :)
       | Disclaimer: out of these two, I only read Clean Code.
        
       | __mharrison__ wrote:
       | This is actually a great read.
       | 
       | I'm in the middle of designing a course for a client on teaching
       | software engineering best practices for data scientists (and
       | folks who live in Jupyter all day).
       | 
       | There seems to be a huge lack of material for these types that
       | aren't "programmers", don't live in an "IDE", and are essentially
       | writing code all day.
        
       | MetaWhirledPeas wrote:
       | I think the reason most people have a problem with Uncle Bob is
       | because they know their own practices are a far cry from his
       | recommendations, and they take his prescriptive and
       | uncompromising advice as a personal attack.
       | 
       | I also wonder how many people interpret his advice as that of a
       | mindless, pedantic dictator.
       | 
       | My own introduction to UB was from some random YouTube video he
       | made about programming languages, so my first impression of him
       | included his humor and his ability to see both sides of an issue
       | while being unafraid of having a strong opinion. I really enjoy
       | speaking with and listening to people with strong, long-marinated
       | opinions, regardless of whether I agree or not. At the very least
       | it means they've put a lot of thought into it, which makes for
       | better discussion and learning.
       | 
       | I also lack a long history of code commits, being more of a
       | dabbler here and there, so perhaps I have a smaller surface area
       | for UB's jabs to land upon. Still, I acknowledge that a Clean
       | Code Nazi would probably rip me to shreds for some of the
       | practices I've followed and some that I continue to follow. But
       | _improvement_ is a much more achievable goal than perfection, and
       | gleaning valuable information is better than being dogmatic.
       | 
       | In the end I _love_ listening to UB talk. I don 't follow all his
       | practices but I _do_ keep them in the back of my mind. If not
       | worth following strictly they are always worth considering,
       | especially the intent behind them.
       | 
       | So when I see his opinions on comments or his opinions on
       | abstraction and variable naming my first instinct is not to
       | lament about how he is poisoning our youth or insulting my code,
       | but rather to ask myself how I can make use of his perspective.
       | I'd encourage others to do the same; it's much more fun that way,
       | not just for programming but for everything.
       | 
       | As for those of you stuck in "Clean Code" hell with oppressive
       | supervisors demanding strict adherence... that sounds like a
       | personal failure, or a personal incompatibility, or both. I would
       | blame the messenger there, not the message.
        
       | jdmoreira wrote:
       | Uncle Bob probably the biggest scammer in Software. What a
       | complete pile of garbage. So much energy wasted in all these
       | design patterns, SOLID and other OOP bullshit.
       | 
       | Turns out you can just pass immutable data in and get immutable
       | data out. Who would have guessed? The whole 90s - 00s Java OOP
       | garbage still gives me nightmares
        
       | ad_hockey wrote:
       | Something I find odd about Uncle Bob's style is the preference
       | for reading and modifying shared state over pure functions that
       | take args. It makes me do a double take when I read a method
       | registerTheCandidateAsPrime() (taken from UB's rewrite) that
       | doesn't take a candidate arg.
       | 
       | How would you unit test those methods? You'd have to directly set
       | the field values, then call the method, then assert on the
       | fields. If the answer is "you don't unit test private methods"
       | then that's completely fine, because I agree with that (perhaps
       | this is implicit from the private keyword, I don't know Java).
       | But I'm struggling to imagine how you would get to those private
       | methods with such a strict adherence to TDD as Bob recommends.
       | Methods like increaseEachPrimeMultipleToOrBeyondCandidate() are
       | quite complex, and would be tricky to build up using TDD if you
       | couldn't exercise them directly.
       | 
       | If nothing else, surely Bob's approach is not thread safe. Call
       | PrimeGenerator3.generateFirstNPrimes() concurrently and they'll
       | trample all over each other. John Ousterhout's stateless version
       | doesn't have that problem.
        
       | ben30 wrote:
       | The primary goal of software design should be to facilitate
       | understanding and modification for future developers, emphasizing
       | the importance of code readability.
        
       | beryilma wrote:
       | "Uncle Bob" is not a software engineer (as he calls himself) and
       | anything he says on the subject is theoretical at best, and snake
       | oil at worst. Can anyone point to any substantial piece of code
       | that he wrote before he can be taken seriously. The code pieces
       | at his GitHub repos, other than style, etc., are just simplistic
       | stuff.
       | 
       | It is probably OK to be thinking on issues related to a field
       | (i.e., software engineering) without being a practitioner in the
       | field, but producing fads-du-jour and selling them as solid (pun
       | intended) theories and expecting to be taken seriously is just
       | ludicrous to me.
        
       | pnt12 wrote:
       | Some software gurus really grind my gears, and Robert Martin is
       | one of them. When confronted with bad advice he gave, he's quick
       | to say it's not meant to be taken literally. Then, gurus like
       | Kent Beck, say that you cannot criticize their approaches if you
       | don't implement exactly as they say. So, while this is not
       | exactly a paradox (different people with different opinions), I
       | feel like gurus make their livings on unfalsiable claims while
       | shaping the world of software engineering.
       | 
       | So, some kudos to Robert for accepting criticism and discussing
       | it, but no cigar for downplaying his own advice when confronted -
       | I also recall a different discussion, where someone confronts his
       | statement "you don't practice tdd you're not a professional", and
       | his answer "it was not meant to be taken seriously".
       | 
       | These people had great ideas but they should be more critical of
       | themselves, eg "here's when not to apply this", "here's where to
       | bend this", not "you're doing it wrong" or "don't take it
       | literally".
        
         | dqft wrote:
         | I don't understand how that works on people. Dog whistling,
         | "Hey, hey, leave me to my grift."
        
         | xiphias2 wrote:
         | The more I tried to implement Clean Code, the more it helped me
         | appreciate Worse is Better approach, which comes from an
         | observation, not a dogma: while all programmers strive for
         | simplicity both in implementation and interface, when they come
         | into conflict, simple implementation usually wins over simple
         | interfaces, as they are easier to modify.
         | 
         | https://dreamsongs.com/RiseOfWorseIsBetter.html
        
       | Applejinx wrote:
       | It's always fascinating to me to see this subject talked about,
       | because I've been programming for years in a niche field (audio
       | plugin DSP development) and have interacted with Clean Code
       | programmers, but I seemingly cannot grasp what they do at all.
       | 
       | This is to the point that, in order to program and do the things
       | I want to do, I have to essentially write nearly everything out
       | longhand, to the point of unrolling things in repetitive fashion,
       | and organizing things in blocks of code separated by comments
       | about what's being done in each block. I can do this so
       | predictably and regularly that my code gets parsed by other
       | people's more Clean Code and ingested as sort of blocks of
       | program behavior to be used in other software, to the point where
       | it's an 886-star repo with 79 forks: not Bob-scale, but then I
       | haven't written books or revolutionized corporate coding.
       | 
       | I've had to learn useful things about where my approach doesn't
       | take advantage of its hypothetical strengths: heedlessly
       | unrolling everything doesn't give you speed boosts, and I've had
       | to learn to declare variables nearer to where they're used. But
       | I've also had to learn that I could do the opposite of Clean Code
       | for performance gains. Back in the day, you could assign
       | variables for calculations to avoid Repeating Yourself, but on
       | modern processors it turns out... in addition to techniques like
       | running calculations in parallel on wide data words that contain
       | different data processed together... you can even take advantage
       | of how eager CPUs are to do math, to avoid creating extra
       | variables. It can be more efficient to just do the math a couple
       | times rather than create a whole new variable just to skip the
       | math.
       | 
       | This world makes sense to me. It acts like assembly language,
       | except it's C (not even C++). I don't know to what extent there
       | are other people who think this way, or struggle to keep track of
       | even simple abstractions.
       | 
       | It's just the context with which I see Bob acolytes, rather than
       | just declaring a variable to not do the math twice, breaking it
       | off into about twelve different methods for seemingly purely
       | semantic reasons, and insisting anything else is stupid. And
       | there I am, producing and re-using reams of shockingly primitive
       | code that seems to work and where I can return to it, even a
       | couple decades later, and have no trouble figuring out what I
       | did.
       | 
       | There's something to be said for being SO stupid that your work
       | just works.
        
       | tdiff wrote:
       | Is there still any apologet of Bob Martin nowadays?
        
       | ptx wrote:
       | I'm surprised that Ousterhout doesn't point out the huge problem
       | introduced with the PrimeGenerator3 refactor: It stores state in
       | static (!) fields, so it's completely unusable in the presence of
       | threads, unless you add a global lock.
       | 
       | Even if Uncle Bob thinks tiny methods are great, why would he
       | introduce the pseudo-constructor "initializeTheGenerator" and
       | make everything static if he needs state? If the helper methods
       | were instance methods instead, the static "generateFirstNPrimes"
       | method could simply construct a new instance to store the state.
        
       ___________________________________________________________________
       (page generated 2025-02-25 23:01 UTC)