#readwise # From Design Patterns to Category Theory ![rw-book-cover](https://readwise-assets.s3.amazonaws.com/static/images/article2.74d541386bbf.png) ## Metadata - Author: [[Mark Seemann]] - Full Title: From Design Patterns to Category Theory - URL: https://blog.ploeh.dk/2017/10/04/from-design-patterns-to-category-theory/ ## Summary From Design Patterns to Category Theory is a blog series that covers various topics from category theory. Here's a list of articles that belong to this series, retrieved on March 17, 2023: - [[Monoids, Semigroups, and Friends]] - [[Functors, Applicatives, and Friends]] - Software design isomorphisms - Unit isomorphisms - Function isomorphisms - Argument list isomorphisms - Uncurry isomorphisms - Object isomorphisms - Abstract class isomorphism - Inheritance-composition isomorphism - Tester-Doer isomorphisms - Builder isomorphisms - Church encoding - Church-encoded Boolean values - Church-encoded natural numbers - Church-encoded Maybe - Church-encoded Either - Church-encoded payment types - Church-encoded rose tree - Catamorphisms - Boolean catamorphism - Peano catamorphism - Maybe catamorphism - List catamorphism - Either catamorphism - Tree catamorphism - Rose tree catamorphism - Full binary tree catamorphism - Payment types catamorphism - Some design patterns as universal abstractions - Composite as a monoid - Coalescing Composite as a monoid - Endomorphic Composite as a monoid - Null Object as identity - Builder as a monoid - Visitor as a sum type - Chain of Responsibility as catamorphisms - The State pattern and the State monad - Refactoring the TCP State pattern example to pure functions - Refactoring a saga from the State pattern to the State monad - Postel's law as a profunctor - The Liskov Substitution Principle as a profunctor - Backwards compatibility as a profunctor ## Highlights With such abstractions, source code becomes easier to understand. Like everything else, there's no silver bullet, but **good coding abstractions can save you much grief, and make it easier to understand big and complex code bases. ==Not only can a good abstraction shield you from having to understand all the details in a big system, but if you're familiar with the abstraction, you may be able to quickly get up to speed==.** While the above definition is great for identifying a good abstraction, it doesn't tell you how to create one. --- **Design patterns are useful in two ways:** - ==**They offer solutions**== - **==They form a vocabulary==** --- In my opinion, however, people often overlook the second advantage. Programmers are often eager to find solutions. "I have a problem; what's the solution? Oh, here's a design pattern that fits!" --- I have no problems with ready-made solutions, but I think that the other advantage may be even bigger. **When you're looking at unfamiliar source code, you struggle to understand how it's structured, and what it does. ==If, hypothetically, you discover that pieces of that unfamiliar source code follows a design pattern that you know, then understanding the code becomes much easier.==** --- There are two criteria for this to happen: - The reader (you) must already know the pattern - The original author (also you?) must have implemented the pattern without any surprising deviations --- As a programmer (code author), you can **help readers (users) of your code. Don't use every design pattern in the book, but when you use one, make it as obvious to the reader as you can: Use the terminology, class names, and so on from the book**. Add comments where your naming deviates. Add links that the novice user can follow to learn more. --- Design Patterns was a great effort in 1994, and I've personally benefited from it. The catalogue was an attempt to discover good abstractions. What's a good abstraction? As already quoted, it's a model that amplifies the essentials, etcetera. I think a good abstraction should also be intuitive. --- **Writers before me have celebrated the power of mathematical abstraction in programming.** For instance, in Domain-Driven Design Eric Evans discusses how Closure of Operations leads to object models reminiscent of arithmetic. **If you can design Value Objects in such a way that you can somehow 'add' them together, you have an intuitive and powerful abstraction.** --- **Notice that there's more than one way to combine numbers. You can add them together, but you can also multiply them. Could there be a common abstraction for that?** What about objects that can somehow be combined, even if they aren't 'number-like'? **The generalisation of such operations is a branch of mathematics called category theory**, and it has turned out to be productive when applied to functional programming. Haskell is the most prominent example. ^9dk84j --- 'things' in category theory are called objects, and while they aren't objects in the sense that we think of in object-oriented design, there is some equivalence. **Category theory concerns itself with how objects map to other objects**. A functional programmer would interpret such morphisms as functions, but in a sense, you can also think of them as well-defined behaviour that's associated with data. --- **objects of category theory are universal abstractions. Some of them, it turns out, coincide with known design patterns. The difference is, however, that ==category theory concepts are governed by specific laws==. In order to be a functor, for example, an object must obey certain simple and intuitive laws. ==This makes the category theory concepts more specific, and less ambiguous, than design patterns==.** --- I believe that **==learning about these universal abstractions is the next step in software design. If you know design patterns, you have a vocabulary, but the details are still open to interpretation. If you know category theory, you have a better vocabulary==. Just like design patterns, you have to learn these things, but once you've learned them, you've learned something that transcends a particular software library, a particular framework, a particular programming language. Learning about functors, monoids, and so on, is a good investment, because these concepts are rooted in mathematics, not any particular technology.** ^8hzxnf --- **Object-oriented programming (OOP) is the dominant software design paradigm. It wasn't always so. When OOP was new, many veteran programmers couldn't see how it could be useful.** They were schooled in one paradigm, and it was difficult for them to shift to the new paradigm. **They were used to do things in one way (typically, procedural), and it wasn't clear how to achieve the same goals with idiomatic object-oriented design. The same sort of resistance applies to functional programming.** Tasks that are easy in OOP seem impossible in functional programming. How do you make a for loop? How do you change state? How do you break out of a routine? **This leads to both frustration, and dismissal of functional programming, which is still seen as either academic, or something only interesting in computation-heavy domains like science or finance.** ---