1. 59
  1.  

  2. 6

    I honestly love this article. It’s reasonnable critics, reflections, about most of the core concepts about simplicity that I try to use and advocate.

    I simply would like to mention that the CORE concept for justifying Clean Code (short funtions for example where the trade off is between concision vs locality):

    • Code is Written Once, and read Hundreds/Thousands of Time
    • Human brains can hold 7 concepts in mind at once (in average)

    This is the driving reason for all of this “simplification”. That’s my claim. Of course there are times the code will not be re-read. But there are also people (me included) who falsely think their brain can handle more than themselves/others easily can indeed.

    1. 8

      Unnecessary complexity is the enemy. Necessary complexity is not.

      The more featureful and rich a language is, the less complex and verbose the applications.

      With the wrong simplification we end up creating more complexity. We can see that in many popular applications.

      The article at http://nomad.uk.net/articles/why-gos-design-is-a-disservice-to-intelligent-programmers.html provides good examples.

      1. 3

        The more featureful and rich a language is, the less complex and verbose the applications.

        With the wrong simplification we end up creating more complexity. We can see that in many popular applications.

        There is a trade off between accepting complexity in a language vs complexity in its artifacts (programs written in the language). It is not a universal that more expressive languages, and therefore shorter programs, are better. Understanding, completely and thoroughly, how language features interact, is a necessary part of mastering that language, and therefore reading and writing programs effectively. Each feature added to the language makes this process harder, especially if those features don’t interact orthogonally.

        There is a place in the language spectrum for a language like Go: a minimal featureset, perhaps even too minimal, but all features basically orthogonal, easy to grok and keep in your brain’s working cache, and therefore easy to produce relatively elegant and coherent program artifacts. Even if many of those artifacts could be better expressed in more complex languages, the overall cost of comprehension is lower, often much lower.

    2. 3

      The most valuable point made in this article for me is that simplicity is not simple, and with that I agree wholeheartedly. However

      The problem emerges when programmers of all types forget that their preferred model of success does not apply to all types of programs, and each choice imposes costs.

      I believe this can be said even more simple. Optimizing for simplicity is different for every code. You just shouldn’t expect that one same tactic will work for multiple code bases.

      I believe the most essential quality of us programmers is inventing the best, unique, approach to optimize for simplicity every time again, given the specific circumstances and the unique requirements of the code we are working on. That is when it gets fun, once you realize that ‘simpler’ is different every time.

      1. 1

        I believe the most essential quality of us programmers is inventing the best, unique, approach to optimize for simplicity every time again, given the specific circumstances and the unique requirements of the code we are working on. That is when it gets fun, once you realize that ‘simpler’ is different every time.

        Yes. But, to a point.

        If working on your program, in your problem domain, requires me to not only learn the abstractions you have built (types, methods, data structures and their relationships, information hierarchies, etc.) but also for example a domain-specific language you’ve invented and used to express them, it is at least possible and in my experience actually quite likely that you’ve made the process of understanding significantly more difficult for disproportionately insufficient benefits.

        In my experience it is almost always better to stick with a common, well-understood language, and work within the its rules, to express your domain. It’s analogous to using e.g. English to produce your novel. It’s entirely likely that you could create a new language from first principles which would allow you to express your ideas more succinctly, or with more precision, or more effect. But that burden is almost certainly too much to bear for any consumer of your work, and it would be ridiculous if that were accepted practice in publishing.

        1. 1

          In my experience it is almost always better to stick with a common, well-understood language, and work within the its rules, to express your domain.

          Fully agreed, of course. Other programmers being able to read the code without much pre-schooling is probably the primary requirement for most code bases, so simplifying needs to happen within the constraints of a well-known language and probably a limited subset of paradigms within that language.

          The point I guess I am trying to make is that I still see developers trying to come up with structuring solutions (design patterns, for example) that they want to be equally applicable to different code bases, perhaps in an effort to make the process of software development more controllable and predictable.

          I argue that circumstances and requirements are different for every project. Better even, the requirements may change over time. As soon as we acknowledge that, it follows that simplicity can only be achieved by applying different tactics every time. This means we can’t know the best approach in advance and there is no clear rule book to follow. In my opinion this is why software development is an eminently creative process.

          Btw, I like the analogy with creating a new natural language for a novel. The choice for a natural language is a purely pragmatic one, and doesn’t have the hype and tension surrounding it that the choice for a programming language sometimes has.

          1. 1

            Ah, okay! It seems I read more into your comment than was actually written.

          1. 4

            They’re arguing very different things. Hickey is arguing that simplicity is objective and universal, this article is arguing that simplicity is subjective and contextual.

            Incidentally, I never got the reasoning why “braided together” is used as an example a bad thing. Ropes and braided cables are both more flexible and resilient than chains, woven fibers are more comfortable than tanned animal skins, nets catch more fish than hooks.

          2. 0

            Error codes are easier to understand than exceptions or Result types, but they don’t carry much information. You’re trading ease of comprehension for difficulty of debugging. Exceptions carry a great deal of information but break the sequentiality of the code. Result types can carry information and preserve sequentiality, but can require a lot of “plumbing” in order to compose and handle different types of errors.

            Isn’t at least this battle won? Rust showed that using Results pervasively works.

              1. 3

                MLs, Haskell, partially Erlang. All of them had something like Result (in Erlang it is just tuple {ok, Result} or {error, Reason}). But from what I see on Wikipedia then the first language supporting ADT was either Hope or ISWIM.