Our last episode was with Fogus. It was a great episode where we learn from his experience as a core contributor. The next episode is on Tuesday, May 6 with special guest JP Monetta. Please watch us live so you can ask questions in the chat.
If you want to learn Clojure, there’s no better way than Beginner Clojure, my signature course for those new to the language. I’ve recently rebuilt the introduction module to teach better, so there’s never been a better time to buy. The point of that module is to give you a deep experience with Clojure (and FP+Data-Driven Programming) as quickly as possible.
Models are messy
I am not a Platonic Idealist. I do not believe that the round table I’m working at is some pale shadow of the ideal circle. At best, circle is a mathematical abstraction that’s easy to define and analyze which happens to approximate the real table well enough to be useful. It is the abstract circle that is the pale shadow of the real table. Circles are just ideas.
So I guess that makes me a Materialist. But as I write this, I realize how much of a process it was for me to arrive at that conclusion. And even describing it took some work. And by learning that about myself, I realized a profound truth: Many people are idealists unconsciously.
One problem is that materialism is often conflated with anti-intellectualism. If the material world is primary, maybe it calls into question studying the idealized world of geometry and algebra. Maybe math isn’t important. But, no, it doesn’t. Materialism acknowledges that geometry and algebra are simply useful mental tools—not the ultimate essence or the source of all truth.
I sometimes wonder, as one does, about the marriage between empirical experiment and mathematical abstraction that has led to the recent explosion of scientific understanding. Why is it that mathematics has been so fruitful at describing the world we discover through experiments? Mustn’t mathematics be a fundamental part of the universe? Is mathematics discovered? Or is it invented by us?
Those are fun questions, but I’m not going to explore them deeply here. I will simply say that it was Buckminster Fuller who got me thinking about all of this stuff. He said there are no zero-dimensional points in the real-world. There are no one-dimensional lines. There are no two-dimensional planes. Everything we can experience is three-dimensional. So he didn’t base his geometry on points and lines and planes. Instead, he always used real objects to explore the nature of space. I still think about that. He went back to first principles and built up an understanding based on empirical exploration instead of abstractions.
The world is messy. Everything is complicated. When I talk about creating a domain model, one of the common pushbacks I get is from people who worry I’m advocating for creating an over-idealized model. One that sounds good but misses all the rich detail of the messy world.
Nothing is further from the truth. In fact, your domain model should enable all of the messy details that you need to capture. The level of abstraction most mathematics achieves is too clean. However, abstraction is the basis for how software works. Software for managing a farm does not operate on real sheep. Yet the sheep are represented.
No, what I’m suggesting is that we must represent the structures we encounter in the world in the software. The structure is often messy. But there is often a deeper, underlying order to it, as in my example of combining simple Boolean predicates to build up a representation of the messy voting laws.
Many real world “laws” are actually rules that apply most of the time but they have a number of exceptions. That itself is the structure we must capture—general rules with exceptions. Many real-world processes are mostly continuous—they’re continuous with a known discontinuity. That’s fine. Those discontinuities can often be handled at a higher level. It’s kind of the complement of finding order at a lower level. Move the messiness to a higher level.
It reminds me a lot of the way I recommend people deal with algebraic properties in property-based testing. People often get caught up looking for extremely regular properties, like the commutativity of addition.
What I recommend is using the formula of commutativity as a starting point—a kind of inspiration.
Ask about whether the order of arguments matter, how they matter, when they matter. You could find some rich patterns there that are worth capturing as properties for your domain.
For instance, merge
for maps is commutative if you know the two maps don’t share any keys. So you start with the basic formula and you adorn it with the real-world detail you’re looking for.
Likewise, the order of checks arriving at the bank doesn’t matter—as long as you have enough balance for all checks to clear:
let bill be the $x check to for the power bill (debit to your account)
let paycheck be the $y weekly paycheck (credit to your account)
That is, if you’ve got the money to pay the bill, it doesn’t matter which order the checks are cleared. But if you don’t have the money and the bill clears first, you might get an overdraft fee.
Remember, commutativity is just a nice idea that corresponds to some things we see in the world. We can adapt it, like any mathematical notion, to make it useful to our purposes. Putting the simpler definition of commutativity ahead of what we encounter in the real world is latent Platonic idealism. We have to reject that idealism. The real world is where the action happens. And its rich detail is what makes it interesting enough to model in software. When you’re building a model, avoid the temptation to make a perfect gem. Instead, aim to honor the imperfections. But don’t be an anti-intellectual and reject modeling outright. Modeling is what enables the magic we wield. So are you an idealist of a materialist—or an anti-intellectual?