gregfjohnson 8 hours ago

This short book is (IMHO) one of the best on software design. To me the main point of the book is the importance of well-designed abstractions. The "surface area" of a well-designed abstraction is small, easy to understand, and helpful as you reason through your code when you use it. The underlying implementation may be deep and non-trivial, but you find that you don't have any need to worry about the underlying internal details.

In short:

A beautifully designed abstraction is easy to understand and use.

It is so trustworthy that you don't feel any need to worry about how it is implemented.

Finally, and most importantly, it enables you to reason with rigor and precision about the correctness of the code you are writing that makes use of it.

  • f1shy 7 hours ago

    That book is a almost perfect summary of what is in my head after 30+ years of programming. I recommend it often to new people, as I see they make the same mistakes I did back then.

    I recommend not loosing time with “Clean X” books, but instead read this book. Also, as noted in other comments, you can only “get it” after some real experience, so it is important to practice an develop a “common sense” of programming.

    • karmakurtisaani 7 hours ago

      I disagree that the "Clean X" books are a waste of time. They lay a nice ground understanding of what to aim for when writing code, in particular when you're early in your career.

      When I was starting as a professional coder years ago, I had an intuitive sense of what good code was, but I had no idea how much actual thought had been put to it by other people. Reading those books was a good step in seriously starting to think about the subject and look at code differently as a craft ("it's not just me, this code smells!" or "hey that's a neat idea, better keep this in mind").

      Definitely would recommend to someone starting out their career.

      Edit: getting downvoted for a reasonable, justified opinion. Classy.

      • f1shy 6 hours ago

        I think you are totally right. The clean X books are not a waste of time. I meant that in the sense of “start here, don’t delay this”. I would recommend: read aPoSD, then Clean X series, then again aPoSD ;)

  • begueradj 3 hours ago

    > A beautifully designed abstraction is easy to understand and use.

    It's like in "Clean Code" where Ward Cunningham said a clean code is a beautiful code.

    Beautiful design, beautiful code, beautiful abstraction, beautiful class, beautiful function ... But is not that subjective and broad ?

noelwelsh 17 hours ago

I come from an FP background, and this book was interesting to me as the author very clearly has a very different (imperative, systems) background. In some cases we have very different opinions, in some cases I'm completely agreed (e.g. "define errors out of existence" is extremely common in FP, usually under the term "make illegal states unrepresentable"), and in other cases I feel they were half-way to FP but couldn't quite get all the way there (e.g. the editor example is a classic interpreter, but they didn't make the connection IIRC.) I only skimmed the book and would like to go back for a more detailed review. Curious if anyone else with an FP background had the same or different experience.

  • Darmani 16 hours ago

    "Define errors out of existence" might sound like "make illegal states unrepresentable," it's actually not. Instead it's a pastiche of ideas rather foreign to most FP readers, such as broadening the space of valid inputs of a function. One of his examples is changing the substr function to accept out of bounds ranges.

    You might be interested in my review. I'm a Haskeller at heart, although the review draws more from my formal methods background. Spoiler: his main example of a deep module is actually shallow.

    https://www.pathsensitive.com/2018/10/book-review-philosophy...

    • hyperpape 15 hours ago

      Does Ousterhout actually say modules must always have a longer implementation than their spec, or just that this is a generally desirable feature?

      If he did, I agree with you, he was wrong about that. I also agree that the unix file API is probably not a good example.

      But whether or not he did, I think the dissection of edge cases would be better off emphasizing that he's got something importantly right that goes against the typical "small modules" dogma. All else being equal, deeper modules are good--making too many overly small modules creates excessive integration points and reduces the advantages of modularity.

      P.S. While I'm here, this is not really in response to the parent post, but the example in the article really does not do justice to Ousterhout's idea. While he does advocate sometimes just inlining code and criticizes the pervasive idea that you should shorten any method of more than n lines, the idea of deep modules involves more than just inlinining code.

      • Darmani 13 hours ago

        I'd say he's in between — he strongly recommends that most modules be "deep."

        I agree that blindly making lots of tiny things is bad, but his criteria for how to chunk modules is flawed.

      • lgas 14 hours ago

        > Does Ousterhout actually say modules must always have a longer implementation than their spec, or just that this is a generally desirable feature?

        I mean the spec is a lower bound on the size of the solution, right? Because if the solution were shorter than the spec, you could just use the solution as the new shorter spec.

        • Darmani 13 hours ago

          Not necessarily. The implementation is very often more defined than the specific. If the implementation is the spec, then it means that even the smallest change in behavior may break callers.

    • Mawr 4 hours ago

      > his main example of a deep module is actually shallow.

      It's not, you're just ignoring what he said:

      "A modern implementation of the Unix I/O interface requires hundreds of thousands of lines of code, which address complex issues such as: [... 7 bullet points ...] All these issues, and many more, are handled by the Unix file system implementation; they are invisible to programmers who invoke the system calls."

      So sure, the `open` interface is big in isolation but when compared to its implementation it's tiny, which is what you've badly missed.

      The book also brings up another example right after this one, that of a Garbage Collector: "This module has no interface at all; it works invisibly behind the scenes to reclaim unused memory. [...] The implementation of a garbage collector is quite complex, but the complexity is hidden from programmers using the language". Cherry picking, cherry picking.

      Then you proceed to not mention all the other key insights the book talks about and make up your own example of a stack data structure not being a deep abstraction. Yes, it's not. So? The book specifically emphasizes not applying its advice indiscriminately to every single problem; almost every chapter has a "Taking it too far" section that shows counterexamples.

      Just so you don't attempt to muddy the waters here by claiming that to be a cop-out, the very point of such books is provide advice that applies in general, in most cases, for 80% of the scenarios. That is very much true for this book.

      Overall, your formal background betrays you. Your POV is too mechanical, attempting to fit the book's practical advice into some sort of a rigid academic formula. Real world problems are too complex for such a simplified rigid framework.

      Indeed, a big reason why the book is so outstanding is how wonderfully practical it is despite John Ousterhout's strong academical background. He's exceptional in his ability to bring his more formal insights into the realm of real world engineering. A breath of fresh air.

    • noelwelsh 5 hours ago

      Nice review. It reminded me of some of the WTF moments from the book :-) I should go back to it and write my own.

    • alpinisme 16 hours ago

      I haven’t looked at the substr function but is that not similar to how you can `take 5 [1,2,3]` or `zip [1,2,3] [‘a’, ‘b’, ‘c’, ‘d’]`

    • musicale 16 hours ago

      Nice and seemingly balanced review.

      Defining errors out of existence should be mandatory for all golang programs.

      • fuzztester 9 hours ago

        err, are you serious, sir?

    • philosopher1234 14 hours ago

      Your review is great! But I think the idea that it’s in opposition to PoSD is not right, I think it’s a further development and elaboration in the same direction of PoSD

  • 0xDEAFBEAD 11 hours ago

    I read most of the book a couple years ago, and I thought it was very good. I wonder if you (or anyone else) can recommend an alternative book that does a better job of describing your perspective?

  • zusammen 15 hours ago

    I read a few chapters and had the same feeling.

  • ninetyninenine 17 hours ago

    I thought the book was stupid. Rehashed a bunch of obvious ideas. It’s a bit harsh, I know, but that’s my honest opinion and I respect other people who like his book.

    I too have a fp background and I felt the author is unqualified to talk about complexity without knowing fp. Elimination of procedures and mutations is a formal and concrete reduction of complexity while the authors definition of complexity is hand wavy. Someone should know about what fp is before writing a book like this.

    Why? Because fp is a basically like a formal structure for software design and the author tried to talk about philosophy without knowing some hard formal rules that are well known in the industry. Not saying these rules are absolute but you can’t talk about design without talking about this.

    The book talks about modularity and things of that nature too and totally skips out on understanding the separation between statefulness and logic. The author completely misses this design concept of how how IO and mutation should be separated from declarative operations. Imperative shell/functional core is a central design philosophy that he doesn’t touch upon. The book is woefully incomplete without talking about this. Whether the authors philosophy aligns with it is open for debate but you can’t talk about what he talks about without mentioning this in a big way.

    • musicale 16 hours ago

      > Someone should know about what fp is before writing a book like this.

      1. Are you quite sure John Ousterhout (who invented Tcl[1], comparing it to Lisp in section 7 of the original paper) doesn't "know about what fp is" as you say?

      2. Do you think that the main reason functional programming hasn't taken off in systems programming is that practitioners are ignorant, or do you think there might be issues with fp systems that prevent its adoption?

      [1] https://web.stanford.edu/~ouster/cgi-bin/papers/tcl-usenix.p...

      • ninetyninenine 16 hours ago

        The book needs to talk about those issues and trade offs.

        Fp with lisp is only a fraction of fp. I of course am talking more along the lines of pure fp which lisp is not.

        • musicale 15 hours ago

          Sure, fp in Lisp might not always be true (scotsman) fp. ;-)

          But omitting fp in the book is not evidence that Ousterhout is ignorant of fp, and there is certainly evidence to the contrary.

          The likely explanation, given that he's developed a number of systems from Sprite to Tcl/Tk to RAMCloud to HOMA, is that he is addressing the current practice of systems programming, which remains primarily imperative.

    • rubiquity 13 hours ago

      FP weenies gone wild 2024. You design web apps with monads. Ousterhout has made systems of actual consequence where mutation is a reality not a fantasy you try to pretend doesn’t exist.

    • kfreds 16 hours ago

      The book plainly states that it is a philosophy for software design. Philosophy in this context is closely related to strategy, which is the art of reducing reality to heuristics, so that we might easier figure out how to reach our goals in a complex environment.

      If the book had been titled "Formal methods for software design" the lack of algorithms for reducing complexity would have been surprising. As it is about philosophy it should not be surprising that it focuses on heuristics.

      • ninetyninenine 16 hours ago

        Applying formal methods derived from functional programming is a design heuristic.

        It’s a core heuristic and philosophy that is foundational in my opinion. The author failing to mention this makes the book missing a fundamental issue central to software design.

        • kfreds 15 hours ago

          Well put. This comment makes your criticism of the book much more clear to me at least.

          I agree with you that the separation of Church and state is a foundational idea of software design and even computing generally. I find it quite beautiful how it manifests in hardware as the two categories of digital logic - combinatorial and sequential. And if we zoom in on the logical expression of memory we see it again - a latch is simply two feedback loops and some combinational logic.

          For what it's worth I thought the book was brilliant. Its ideas weren't all obvious to me before I read it. It also inspired me to read Parnas, Wirth, Hoare, and study the Go runtime and compiler.

          What should be obvious is this: the fact that the ideas were obvious to you doesn't mean they are obvious to everyone.

          Secondly, complexity has many meanings. Managing complexity is incredibly important in the realm of security. I've been dabbling in security for 25 years, but I would certainly not claim to have a deep understanding of functional programming. Nevertheless I understand complexity quite well. I think that's what bothered me the most about your original comment - the idea that people without a background in FP are unqualified to talk about complexity.

          • mrkeen 7 hours ago

            > I would certainly not claim to have a deep understanding of functional programming.

            From a philosophy-of-complexity perspective it's not needed, all you need to ask is: will my code give the same output given the same input? (And if not, there's your complexity!)

            Of course, this is a big ask of a programmer. Leaving determinism up to the programmer in an imperative setting is like leaving memory-safety up to the programmer in a C setting.

    • vendiddy 16 hours ago

      I too write FP code but I found this book very valuable in how he treats complexity and his concept of "deep modules".

      I acknowledge that he does not cover purity and mutations as a source of complexity (and they are big sources of complexity) but I don't think that merits dismissing the entire book on those grounds.

      • ninetyninenine 16 hours ago

        I’m not dismissing the entire book. It has merit in what it mentions but it’s missing core foundational concepts.

        Because it misses these concepts the book isn’t good in my opinion.

        • WillAdams 13 hours ago

          In what ways could these concepts be discussed in the structure of the book in terms of currently prevalent programming practices?

    • UniverseHacker 16 hours ago

      If this is so stupid and obvious, why does apparently 99.99% of software designed by professional engineers seem to be designed by people completely oblivious to these ideas and considerations?

      Following these philosophical principles themselves- it seems like a simpler and more accessible treatment of these ideas would be vastly more effective then a more rigorous and complete one- because the ideas are indeed simple.

      • ninetyninenine 16 hours ago

        > If this is so stupid and obvious, why does apparently 99.99% of software designed by professional engineers seem to be designed by people completely oblivious to these ideas and considerations?

        It’s similar to why a big portion of the world believes in Christianity and another portion believes in Buddhism. Basically only one or none of these religions is correct rendering at least one population of people believing in a completely made up fantasy concept.

        Much of what is preached in software is religion and what is preached by the majority can be completely ludicrous. The majority believing or not knowing something doesn’t mean anything.

        • vouwfietsman an hour ago

          No, its not similar at all.

          Parent is telling you: "if A is so simple and obvious, why does nobody do A", your counter argument: "if many people believe A it does not mean it is true". This is entirely unrelated, the point is that these things are NOT obvious to the average programmer, he/she would benefit from learning this, and claiming that these things are broadly "stupid and obvious" is petty and false.

          Also, the things you're saying just don't add up with your criticism that the author is missing some fundamental part of software philosophy. If the author is only missing something, then it still makes sense for the majority to learn the things he is saying, at least, as explained by your parent.

          Finally, if anything can be compared to religion, it surely is the evangelism of functional programming zealots.

        • graemep 11 hours ago

          > It’s similar to why a big portion of the world believes in Christianity and another portion believes in Buddhism. Basically only one or none of these religions is correct rendering at least one population of people believing in a completely made up fantasy concept.

          You have picked religions with as little as possible in common. It would be rather different if you had picked any two monotheistic religions for example: one could be entirely right, and that would mean the other was partially or mostly right.. Despite your choice, there are many things in common: a path to redemption, monasticism, wealth being a barrier to redemption, meditation and mysticism... its quite possible those common elements might be right.

          The same with software. Some things that are widely believed may be true and other false.

        • UniverseHacker 15 hours ago

          Religious “truths” are not factual truths- they are better thought of as psychological technology or techniques, and are “true” if they work for the intended purpose. Many conflicting religious “truths” are all “true.” Even calling them truths is only done to make the religions accessible to people that can’t mentally process nuance, and the techniques only work for them if labeled as truth. Intelligent religious scholars understand this well- for example Mahayana and Vajrayana Buddhism both teach nearly opposite and factually incompatible perspectives on almost everything, yet are often both used by the same religious teachers for different pupils as appropriate.

          The same is true for software design- an approach is not literally true or false, but either works for its intended purpose or does not. Conflicting philosophies can both be “true” just with different underlying goals or values.

          To circle back here, my point is that this information is presented in a simple way that will let people reading it design better software. Saying they have no right to present it without a much less accessible and more complex framework that would likely make it less useful to the intended audience does not make sense to me.

          FWIW, I am also a functional programmer, but would love to see people that are not follow some of these ideas.

          • drdeca 12 hours ago

            1 Corinthians 15:13-19 (NIV) : “ If there is no resurrection of the dead, then not even Christ has been raised. And if Christ has not been raised, our preaching is useless and so is your faith. More than that, we are then found to be false witnesses about God, for we have testified about God that he raised Christ from the dead. But he did not raise him if in fact the dead are not raised. For if the dead are not raised, then Christ has not been raised either. And if Christ has not been raised, your faith is futile; you are still in your sins. Then those also who have fallen asleep in Christ are lost. If only for this life we have hope in Christ, we are of all people most to be pitied.”

            ——

            There is only one kind of truth. “All truths are God’s truths.”

            If Christianity is not true, then it is false. If Christianity and Buddhism strictly contradict each-other, then at most one of them is true.

            Christianity is not meant to be a, what, psychological trick? It makes claims, and these claims should be believed if true and disbelieved if false.

            • UniverseHacker 11 hours ago

              It's no trick, it's a spiritual path that can't be understood without following and practicing it- the path very much leads to something real that cannot be experienced or explained any other way. Everything Christianity teaches is true in the sense that I mean here. You are not understanding what I am saying and I do not personally know how to explain it more clearly[1], which, as I explained above, is why religions pragmatically also offer this view you hold as the official explanation to lay people, despite being obvious nonsense as an objective truth to anyone that thinks very hard about it.

              I posit almost all intelligent monastics and religious people are smart enough to tell the difference between objective truth and religious truth- but it is taboo to explain this to lay people as they will be confused and think it means the religion is "fake" or a "trick", however I don't feel the need to respect said taboo. Perhaps I will learn to respect it by trying to explain it to people unsuccessfully.

              [1] David Chapman may be able to: https://vividness.live/visionary-and-objective-truths

              • graemep 11 hours ago

                > I posit almost all intelligent monastics and religious people are smart enough to tell the difference between objective truth and religious truth- but it is taboo to explain this to lay people as they will be confused and think it means the religion is "fake" or a "trick", however I don't feel the need to respect said taboo.

                That is positing a conspiracy theory level of deception.

                At least as far as Christianity goes, the "intelligent monastics and religious people" write down their beliefs, and have done so for millennia, and they read each others writings. What you suggest might be possible with an oral tradition, but not with a written one. Christianity is very much concerned with objective truth, and one of the distinguishing characters of it (and some other religions too) is a belief that there is an objective truth.

                • UniverseHacker 10 hours ago

                  It's no great conspiracy for a religion to have tiers of understanding and nuance reserved for people more intelligent and dedicated in practice- that is one key purpose of having a distinction between lay people and monastics. The mystique of this is openly part of the draw for people to sign up for it.

                  There's no deception- it's something that (as this discussion shows) is very subtle and dangerous to the religions when misunderstood- but not dangerous when understood correctly. It is written down repeatedly in religious texts, in a subtle way with plausible deniability, but clear to those that can read between the lines. Writing in that way was the essential basic art of any intellectual until very recently, it is only now (sort of) safe to plainly state nuanced philosophical and religious concepts without facing persecution. Nietzsche argued you still should not do so even if you can.

                  It's also both quite obvious and relatively unimportant on its own to people that would be capable of understanding nuance, and could be quite harmful to the faith and the stability of the religion of those not able to understand.

                  • graemep 10 hours ago

                    > It is written down repeatedly in religious texts, in a subtle way with plausible deniability, but clear to those that can read between the lines.

                    Can you give me an example of what you mean? From Christianity, as its the religion I know most about.

                    • UniverseHacker 10 hours ago

                      I'm not a scholar of Christian literature (or a Christian), and I don't speak Latin, so it would hardly be appropriate for me to pull out a specific quote and insist "this is what they really meant." In truth, my original source for this was my own understanding being raised in a Christian church- and voicing this perspective out loud in church as a young kid didn't go over well, as you might imagine. To me as a young kid, it was immediately obvious that there were deeper ethical principles being explained in these stories, and one had to be an idiot to be worried about if they were objective factual details or not, when the point was clearly to understand and embody the message- to practice and live it. One was called to have faith that living these principles wholeheartedly was the right thing to do and would lead to real spiritual growth, not to have faith that some particular guy built a particular boat- such things are irrelevant.

                      However St. Augustine is someone that I am particularly certain had a clear understanding of this, and I can see it in how he frames most of his ideas.

                      Another example, would be that ancient religious texts are not careful at all to avoid making numerous objectively factual contradictions- as the anti-christian crowd loves to point out over and over while also completely missing the point. If the people writing them thought that was important, they would have avoided doing so- contrary to modern opinion, ancient theologians and philosophers like St. Augustine were not idiots.

                      William Blake is a more modern person that, while just about the furthest thing from a monastic, clearly had a deep understanding of what I am talking about. Carl Jung also extensively understood and discussed a lot of esoteric things in Christianity including this, and wrote about them in a relatively clear modern way.

                      • graemep an hour ago

                        > However St. Augustine is someone that I am particularly certain had a clear understanding of this, and I can see it in how he frames most of his ideas.

                        Can you give me an example of one?

                        > To me as a young kid, it was immediately obvious that there were deeper ethical principles being explained in these stories, and one had to be an idiot to be worried about if they were objective factual details or not

                        Again, an example? You are suggesting for example that there is no redemption or afterlife but they convey some point?

                        > If the people writing them thought that was important, they would have avoided doing so- contrary to modern opinion, ancient theologians and philosophers like St. Augustine were not idiots.

                        Does Augustine contradict himself? In a single work (different views in different works could be a change of mind)?

                    • roenxi 3 hours ago

                      You might enjoy this comic:

                      https://www.smbc-comics.com/comic/2010-06-05

                      It makes a humourous and compelling argument that a big part of Christianity is encouraging its adherents to follow the game-theoretic optimum in a way that will convince someone even if they are a bit credulous.

                      If you approach the bible with a good knowledge of negotiation and game theory, a lot of it can be interpreted in that light. There is a lot of good advice to get people to move to the global optimums that can be reached if everyone cooperates. It isn't subtle about it. There is no conspiracy to hide that it is good advice even to someone who doesn't particularly believe in afterlives, miracles or god-given ethics. There is a very neat division between the common read and the read of someone with a good grasp of social dynamics, negotiation and game theory. No conspiracies. Just a lot of people who can't handle complex social negotiation.

                      • graemep 2 hours ago

                        Its hardly a new idea. One problem is that there is a lot more to religion than ethics. It also assumes that religious rules of behaviour are global optimums. It fails to explain why religions spread too - why would people believe in the religion that promotes cooperation, rather than one another one? In fact, I would argue, that, in the west, far more people are moralistic therapeutic deists than Christians.

                        There is also a lack of evidence it works. I do not think Christians are consistently greatly more socially cooperative than atheists. Maybe more inclined to help people on the fringes of society - e.g. running food banks here in the UK, very active in poverty charities globally but while good, I cannot believe it has a sufficient consistent effect to provide an advantage to a society that follows it.

                        Fear of hell as a motivator is limited to some Christian denominations but is not often mentioned by other denominations (I am mostly familiar with Catholic and Anglican churches) or in the Bible, or Christian writings, or in sermons or in religious discussions. Christian universalists and others do not believe in any form of hell at all!

                        It might work with a religion once established (religious societies do better because of that cooperation) but it does not explain how religions spread in the first place. Its a lot more likely to apply to a religion that has been long established in a relatively stable setting so it is credible as an explanation of much of ancient Jewish law that seems strange to us now (e.g. what to eat, not plucking fruit from young trees etc) that often seems off from a modern perspective.

        • musicale 15 hours ago

          Good explanation, really. Imperative systems programmers reject one or more of the fp commandments (perhaps finding them impractical), and are probably heretics in the eyes of the fp cult.

    • shinycode 16 hours ago

      Interested if you can give other books/resources on the subject (not fp though)

      • ninetyninenine 16 hours ago

        Can’t because fp is in itself basically a design philosophy that can be explained in 3 axioms.

        Segregate mutation from logic

        Segregate IO from logic

        Eliminate procedures from logic.

        The third axiom is sort of for free as it falls out automatically when someone enforces the first two. That’s basically imperative shell/functional core design philosophy which is basically identical to the rules of pure functional programming.

        https://medium.com/ssense-tech/a-look-at-the-functional-core...

        With fp you can think of these rules enforced as a language. Outside of fp we call it functional core / imperative shell and these rules can be enforced in an imperative language as a core design philosophy.

        • analog31 11 hours ago

          I also found this useful. I'm not a software developer, but use programming for problem solving and prototyping. Still, things that "look like software" sometimes leak out of my lab. FP always set off my BS alarm, because in my simplistic view, the whole world has state. But even for my crude work, a sort of "separation of powers" helps clean up my programs a lot, and code that doesn't need to have side effects can be a lot cleaner if it's not mixed with code that does.

          • skydhash 9 hours ago

            FP does not deny state, it merely segregate it between the before and the after, and everything that is in between is transient. Then you combine all the individual functions, piping them into each other and the whole reflect the same structure. Then, it becomes easier to reason about your logic as you only have two worry about 2 states: the input and the result. No need to care about individual transformations and ordering like you do in imperative.

        • kfreds 15 hours ago

          Thank you. I found this comment illuminating. I too am very interested to hear any book recommendations you have on the topic.

          What are your favorite books on software design, functional programming, and/or computing generally? What are your favorite papers on the topic of complexity (as FP defines it)?

          • BoiledCabbage 9 hours ago

            "Domain Modeling Made Functional" is a great read and sits next to a lot of these topics. Very easy to follow and learn from even if you don't know (and never intend to use) the language.

        • rramadass 12 hours ago

          I would like to echo the user kfreds sibling comment. I don't have a FP background either and hence would very much like to hear your recommendations on books/videos/articles to understand FP and design the "FP way".

      • vendiddy 16 hours ago

        I disagree with the op and found the book to be very good. If you haven't read it, I would recommend reading it and judging for yourself.

Warwolt 2 hours ago

I read this book with some colleagues at a work book club, and I think it's interesting how split the opinion on the book is among readers.

My impression is that there's some good ideas in the book, but it suffers from not being thorough enough on a theoretical level. Many definitions given are NOT consistently used, the book frequently falls back on discussing things in a very OOP centric way, and a lot of stuff came across to me as just opinion pieces.

Some stuff I found was excellent, like the notion of module depth.

When reading reviews on Goodreads, there's a similar disparity between people who really liked it and people who are critical of it.

  • rodolphoarruda an hour ago

    > the book frequently falls back on discussing things in a very OOP centric way

    I do procedural most of the time. Do you think I can still benefit from reading the book? Judging from the summary in blog post, it seems to be a nice read even for non-OOP code. It's just my first impression though.

abcde777666 8 hours ago

A lot of these types of books and posts only deal with the low hanging fruits of software design difficulty, such as the provided discount service example.

The trouble is that kind of thing's pretty much software development common sense - only the inexperienced don't know it.

The true difficulties of software development are often must gnarlier in my experience.

For instance, making architectural choices for large and dynamic software systems, such as say a cutting edge game engine - that can be really hard to get right, and there's not always a lot of sage advice out there for how to navigate it - and not just for game engines but for any equally or more complex software.

I guess my point being - I'd love to see more effort into addressing the hard design stuff, and less repetition of what's already been established.

  • f1shy 7 hours ago

    I’m with you with 99% of those books. But this one is little bit different, IMHO

  • AndyMcConachie 4 hours ago

    Every example I see in programming books that say something like, "You should do it this way." Always come with the caveat of, "It depends."

    For the hard stuff that you would like to see covered the "It depends" part becomes more important. The correct way of handling the really tough cases you're talking about are extremely circumstancial. Thus, a book discussing them generally wouldn't really work. What would probably work better are examples of these tough design issues that include the actual code and some discussion about why specific design decisions were made.

    I like reading code from people who had to make tough trade offs in the real world and hearing in their own words why they made the decisions they did. I loved reading Lion's Commentary on the UNIX OS 6th edition, for example.

suzzer99 10 hours ago

Something bugs me about that first example. We started with two classes that had trivial constructors, and changed them into classes that require an instance of DiscountService be supplied to a constructor. That doesn't feel like less complexity to me.

I'd probably just make applyDiscount a static utility method that the two classes import and invoke on their own, at least until it becomes obvious that something more involved is needed.

  • exoji2e 8 hours ago

    Yes, and also it’s weird to get a negative shipping cost (-5) for US and code SUMMER2024. Typically you would only apply the discount code once and not both to shipping and the total order value.

bvrmn 15 hours ago

Sadly article's author doesn't touch the main idea of the book: component's public API should be narrow as possible. John makes a great deal of that with concrete examples.

  • ilrwbwrkhv 9 hours ago

    This. That is the biggest idea and also the most applicable and the easiest to understand when your complexity is going through the roof.

    For example in Ruby land it is very common to make a class and then make a lot of small tiny methods which are one liners or two liners.

    I had asked him directly about this and his answer was to avoid doing it.

    Since then my Ruby and Common Lisp code has become much better.

    I have since moved to rust, but the point still applies.

    • theonething 9 hours ago

      > make a lot of small tiny methods which are one liners or two liners.

      I'm presuming you mean public tiny methods? Having private ones like that can be good if makes sense to do so (encapsulates logic, increases readability, etc)

      • ilrwbwrkhv 8 hours ago

        Yes public "deep" methods. But even private methods I have been more conservative.

        It is after all an API for you!

        Basically the idea that you shouldn't have long methods is something I don't believe in anymore. Even Carmack made a similar point: http://number-none.com/blow/blog/programming/2014/09/26/carm...

        • lll-o-lll 2 hours ago

          I never believed this, even when I was compelled to do it.

          What are we achieving in these plethora of small methods? There are many potential negative patterns that eventuate.

          - Lifting variables into “global” (object) state. In more complex classes, it’s often hard to even identify that this has happened. Is this permanent object state, or just an internal temporary variable that made it easier to leap around methods?

          - Making code harder to change as variables must be lifted into method parameters (so changing a variable, or adding a new one leads to multiple modifications). Method1 calls Method2 calls Method3 with a “dependency” that Method2 never needs.

          - Poor naming leading to obtuse code. DoThingPart1, DoThingPart2

          - Harder to follow code by having to jump around the file (or worse, multiple files).

          There are better and worse ways to structure code to make it easier to read and reason about, however blind metric approaches are not the way.

sarchertech 14 hours ago

It’s a great book. I feel like a lot of the midlevel engineers I’ve worked with over the years who read clean code and stopped there would benefit greatly from it.

ricardobeat 13 hours ago

While I heartily agree with limiting complexity as a ground rule, the example given is not a great one.

First, it’s more about repetition/poor design than complexity. Second, creating a separate service class for applying a discount is adding unnecessary complexity. You’ll end up with a pile of DiscountService, TaxService, ShippingCostsService, and so on, and they will be sewn together like patchwork. It seems to be a common pattern in Java but surely there are better ways?

ozgrakkurt 3 hours ago

Focusing on these things feels like focusing on training technique too much when going to the gym. In the end mostly what matters is getting things done and keeping it as simple as possible. And simple is very subjective, everyone’s simple is what is simple to them. Feels like everyone should pick a technique and master it then reuse it, there is not much point on finding a global simple/elegant

WillAdams 15 hours ago

Agreed.

I read this book recently, one chapter at a time, and after each, reviewed the code for my current project, applying the principles to it in a re-write --- it helped a lot.

Highly recommended.

vkazanov 17 hours ago

In the oop age of arch I felt like I had no mouth (and I had to scream).

This book, as well as the data oriented design approach, is what made things right for me.

galaxyLogic 11 hours ago

“The idea behind exception aggregation is to handle many exceptions with a single piece of code; rather than writing distinct handlers for many individual exceptions, handle them all in one place with a single handler.”

This seems similar to how events are handled in a web-browser. Each element can handle its own event-handlers. But equally well there can be a single event-handler for each event-type in a containing element, perhaps at the top-level only.

If you define event-handlers of a given type for all DOM-elements of the page in a single location it becomes much more flexible to modify how and which events are handled and for which DOM-elements.

So we could say that "error" is just one of the event-types, errors can be or could be handled by the same mechanism as events in general are. Right? Or is there clear categorical difference between error-events and other types of events?

indoorcomic 12 hours ago

I disagree with the examples in the second idea. The "bad" example is easier to understand and maintain at a glance in my opinion. Looking at the RegisterUser method, I can immediately see the steps it takes to register a user, whereas the "good" example I have to think about it a bit more. Of course, this is a simple example so not much thinking needs to be done, but in a more realistic application I think this would hold much more truth. In projects I've worked on I've seen methods get incredibly bloated due to this. I certainly do agree that "splitting things up for the sake of splitting them up" can be bad practice, I'm just not sure this is the best example to demonstrate that.

  • estevaoam 11 hours ago

    I agree. The main function of a component should describe what it does, similar to describing the algorithm in natural language. I have been following this pattern with success. It is much easier to understand things at a glance.

cdpd 5 hours ago

I think that the first example tackles such a naive approach about how to implement the discount code, IMHO I would ask more about the business logic around it. Why is a discount applied to both the order and the shipping? are they the same thing? What if the company applies discounts to only shipping and not orders itself?

Maybe it comes from experience, but I would focus on understanding the business side first and the see if the abstraction is feasible (To be honest the first approach in the example is not even bad given that they are two "independent" business entities)

onemoresoop 17 hours ago

I love this website’s format, it seems very pleasant to read.

  • asimpletune 17 hours ago

    I came here to say the same. Having the navigation on the bottom is great too, with it appearing when you scroll up. Kudos to the owner.

tpoacher 4 hours ago

The telegram channel is a great idea. Subscribed!

PunchTornado 4 hours ago

I view that some of his principles are against what uncle Bob is preaching. And I agree with him, especially on the focus to reduce complexity. Uncle Bob preaches modularity and encapsulation over everything and you end up with a thousand 2 liners classes and methods.

khana 15 hours ago

[dead]