7 Guiding the design with properties

 

This chapter covers

  • Formal definitions of correct
  • Designing around algebraic properties
  • Parallel universes and how to hop between them

Writing software is hard. It's an endless fight against complexity. We've spent years coming up with design patterns and frameworks to control this complexity, but the complexity is unyielding. Development slows. Bugs rear their heads. The gap between what the requirements say the software should do and what it actually does grows steadily over time.

We all want to keep the complexity at bay, but opinions differ on how to do it. How do you decide when a design approach is "better?" When it’s SOLID? Or uses more OOP? Less? Design discussions often stalemate around mutual accusations of "complexity." One approach gets sanctified as “simple,” all others denigrated as “complex.”

But what does any of that mean? What is being measured?

In this chapter, we’re going tackle a meaning for “simple” that’s based around algebraic properties. If we can reason about the set of values that our code denotes, and what the relationships between those values mean, it has earned the label of “simpler.” If not, we keep digging until we find it.

Writing clear code requires clear thinking. Algebraic reasoning is how we do it.

7.1 We begin with an exercise

7.2 Thinking Algebraically

7.2.1 Standing on Shoulders, Not Toes

7.3 Noticing algebraic operations in every day code

7.4 The algebraic properties of binary operations

7.5 Invariants, Properties, State, and an upside-down capital A

7.5.1 Every possible state? Surely too inefficient to be practical!

7.5.2 Expressing these ideas without code

7.6 Associativity

7.7 Noticing more properties

7.7.1 Ordering as a property

7.8 Monotonic Relationships between inputs and outputs

7.8.1 The properties that define what it means to be correct

7.9 Jumping between universes

7.9.1 Dealing with the IDE telling us we're doing it wrong

7.9.2 Lifting Binary Operator into the universe of Optional

7.9.3 Moving our algebra into the universe of Optional

7.10 The finished implementation

7.11 A final note on representing algebraic ideas in code

7.12 Wrapping up

7.13 Summary