PurelyFunctional.tv Newsletter 461: Rules of thumb don't scale
Sign up for weekly Clojure tips, software design, and a Clojure coding challenge.
Last week's issue was confusing. There were lots of ideas swirling around. Here they are in bullet form:
- We should analyze the structure of the domain. An important structural feature is alternative.
- We should analyze the features of our language for ways to represent that alternative. I identified three in Java: enum, interface, and data class. There are probably more.
- We need a principled way to choose between them when designing our software. We need to consider the semantics of the language feature and choose one that meets our systemic needs.
- How often the domain concept will vary is significant to the software system. We should choose the language feature that aligns with the volatility of the domain concept. There are other important factors besides volatility.
- This method focuses on substance (alternative) first and style (which representation) second. It is superior to design rules of thumb ("always/never use an interface for this or that") or principles such as Open/Closed which focus exclusively on style.
That's a lot of stuff to say in one essay! I want to focus on the last point in this week's essay.
Design Idea 💡
Rules of thumb don't scale
This essay continues the series about Domain Modeling.
Let's imagine we're planning a bank building, and it's time to design the doors. What kind of opening hardware do we put on each side of the door?
We could follow a rule of thumb: Put handles on the "pull" side and a push plate on the "push" side. We would have a decent door experience.
Or we could follow another rule of thumb: Use similar hardware on both sides to increase symmetry. Then we'd have a visually pleasing yet confusing door experience.
Or what about another rule of thumb: Design the door to require less hardware. For instance, you could make it swing both ways.
Design schools differentiate themselves by their rules of thumb. They sometimes agree on a finished door, but they follow conflicting paths. Which one is correct?
There are no universally correct choices. When designing a door, we must make many choices, including how it locks, the hinges, the material, etc. The design always starts with understanding the purpose of the door.
There are doors with different purposes. Some doors welcome strangers off the street (customers). Others allow easy escape but no entry (fire escapes). Yet others signal an area private to some small group of people (employees only!). Each of these doors requires different construction. From the purpose and the systemic context (cost, material availability, culture, etc.), we decide.
I have my opinion based on my own taste: Make the most usable door (the first rule of thumb). Likewise, I have my own opinion about what structure to use for representing coffee size (data class). But let's be realistic: One person's opinion is not that helpful even if based on lots of experience. Do we need another book filled with software design rules of thumb?
I want to write a book that does better than that. And that's why I presented the three language constructs the way I did---in terms of what they afford. Even if I would never use an interface for that myself, some Java folks would. And who knows? If you change the requirements just a little, I might use an interface.
Programming is like designing a door. We can't say "program to interfaces" (Open/Closed principle). Nor can we say, "only use interfaces for such and such, but not the other thing." Those are rules of thumb with the same problems as "make the doors symmetrical."
We need to uncover deeper truths about our craft. Rules of thumb won't cut it.
Awesome book 📖
The Maintenance Race by Steward Brand.
Who doesn't love Stewart Brand? He seems to only write books that bring a new perspective. This one is no different. Though it's only one chapter of a longer, ongoing work, it's really good! What lessons can software engineers learn from sailboat maintenance?
New podcast episodes🎙
Two new episodes since last time I mentioned it:
- I share My Feelings About Static vs Dynamic Typing. More my feelings on the debate between these two camps. I also lament about why we can't listen to each other.
- I coin the term The Christopher Alexander Effect, which describes Design Patterns and Agile work sometimes, for some people, but not for others.
Book update 📘
Grokking Simplicity is still selling strong. I love getting messages on Twitter or over email about how it is affecting people's coding. Here's one:
And did you know there's now an audiobook version available? What? I haven't listened to it (I actually had nothing to do with it). You can hear the first chapter on the Manning site.
You can order the book on Amazon. Please leave a rating and/or review. Reviews are a primary signal that Amazon uses to promote the book. And they help others learn whether the book is for them.
You can order the print and/or eBook versions on Manning.com (use TSSIMPLICITY for 50% off).
Pandemic update 😷
I know a lot of people are going through tougher times than I am. If you, for any reason, can't afford my courses, and you think the courses will help you, please hit reply and I will set you up. It's a small gesture I can make, but it might help.
I don't want to shame you or anybody that we should be using this time to work on our skills. The number one priority is your health and safety. I know I haven't been able to work very much, let alone learn some new skill. But if learning Clojure is important to you, and you can't afford it, just hit reply and I'll set you up. Keeping busy can keep us sane.
Stay healthy. Wash your hands. Wear a mask. Get vaccinated if you can. Take care of loved ones.
Clojure Challenge 🤔
Last issue's challenge
This week's challenge
Primes in a number
Another contrived math problem. This one I think is actually pretty hard. It's got detecting primes, string manipulation, and combinations.
Your task is to write a function that takes an integer and finds all primes that are substrings of the decimal digits of that integer.
(find-primes 2) ;=>  (find-primes 22) ;=> [2 2] (find-primes 717) ;=> [7 7 17 71] (find-primes 1) ;=>  (find-primes 44) ;=> 
- Return the primes in ascending order.
- If a prime appears more than once, it should be in the returned sequence that many times.
Thanks to this site for the problem idea, where it is rated Very Hard in Java. The problem has been modified.
Please submit your solutions as comments on this gist.