talk: https://www.youtube.com/watch?v=rI8tNMsozo0
slides: https://www.slideshare.net/evandrix/simple-made-easy
"Simplicity is prerequisite for reliability" -- Dijkstra
Simple:
- vs complex
- one concern / role / task / concept
- about interleaving of concerns, not cardinality (e.g. not limiting classes to one function)
- objective
Easy:
- vs hard
- "to lie near"
- easy to acquire, easy to understand, near our capabilities
- the limits of our mental capacity are often not talked about
- subjective / relative
Not the same thing!
Limits
- 7 +/- 2
- We can only consider a few things at a time, and intertwined things (complex things) must be considered together.
- complexity makes understanding more difficult
- if you can't understand it, you can't change / improve it
The growing elephant: the code we've already written
- as the elephant grows, it gets harder to push around
- our whole job is to change software
- in the long run, complexity will domniate your velocity
Simplicity buys you opportunity
- architectural agility is a huge win
- simplicity makes it easy to change things
"Programmers know the benefits of everything and the tradeoffs of nothing"
- this touches on another key idea: no bad decisions in tech, only tradeoffs!
"Who wants to be in this band?"
- touches on a related idea: you get better at what you spend your time on, and your time is an investment.
- should you invest the next six months using an ORM, or just getting better at SQL?
Another way to state some of this:
- When considering a decision, ask "how easy/difficult will it be to change this decision 6 months from now?"
Don't complect my thing bro!
Often complexity isn't consciously chosen, it is the default result of choosing what is easy. So consider simplicity when making a tech decision.
We can't significantly improve the limits of our mental capabilities, so it is crucial to work within those limits, which means choosing simplicity whereever possible.
Pure functions are simpler and easier to test than methods on objects.
Syntax: order of arguments (vs a single dictionary arg)
ORM's: consider instead the yesql approach (sql as a first-class part of your codebase)
- https://github.com/krisajenkins/yesql
- not hard to adapt this to other langs:
Examples of complexity which are commonly chosen these days:
- ORM vs SQL
- Eventual consistency vs transactions
- microservices vs monolith
Choosing simplicity often requires upfront cost, but the payoff is better velocity in the long run.
Simple example: order being a source of complexity
[depth width height]
- Using a set clearly communicates that order does not matter
- Using a dictionary avoids this particular ordering problem
- Example of changing
[name email]
to[name phone email]
Queues can be a good way to decouple / decomplect two pieces of software
Choosing maps instead of classes -- Swift's value types can be a middle road (as long as you stick to Codable
).
Can you move it?
Subsystems. Let data be the boundary (between services), rather than verbs / funcalls.
TODO:
- think more about his points about:
- inheritance / switch statement / pattern matching vs polymorphism
- conditionals vs rules?