Death by design patterns, or On the cognitive load of abstractions in the code
It&#x27;s not the number of abstractions, but the quality of abstractions. If abstractions reduce cognitive load, they are good. If abstractions increase cognitive load, they are bad. Often times good abstractions are obvious within the problem domain.<p>To this end, I think Haskell, in its pursuit of the purest, can lead to incredibly-high cognitive load abstractions that make reading code daunting. It feels good when writing it, but feels awful when reading it. Sometimes applying the DRY principle can be bad if the thing you are generalizing will lead to higher cognitive load for people referencing it.<p>Also I think abstractions vary in quality depending on the language the abstraction is embedded in. Functional paradigms in C++ are thorny to work with; even though functional paradigms are good abstractions in general, if the language doesn&#x27;t support it first-class (i.e. the cognitive load of using them is high), then they are not good abstractions.<p>You can also consider maps in a language like Clojure, where maps are almost &quot;zero-class&quot;; it&#x27;s like the language was built for maps. Nested maps have incredibly low cognitive load in Clojure (not only because the syntax supports it, but also because functions are standardized). Nested maps in Common Lisp, however, are not as nice as those in Clojure; you have to import non-standard libraries in order to deal with them (and even more obscure libraries to support Clojure-like read macros).<p>The key question is: when someone else reads this code, how much do they need to &quot;reconstruct&quot; the context? Can they get away with not reconstructing the context? And if they need to, how fast can they do so, via appropriate naming, comments, and types?