PurelyFunctional.tv Newsletter 448: Domain model convenience
Sign up for weekly Clojure tips, software design, and a Clojure coding challenge.
Design Idea 💡
Domain model convenience
This essay continues the series about Domain Modeling.
Convenience is one of those topics I'm still deciding where to place into the theory. From one perspective, part of the purpose of domain modeling is to make code easier to read, write, and maintain. Yet when I imagine successful domain models, nothing was ever sacrificed for convenience. Yet it still feels important. Let's explore it a little more.
What is convenience?
Convenience is all about ease. We break convenience into two parts:
- Convenience for the programmer
- Convenience for the computer
For the programmer, convenience means it is easy to write correct solutions, easy to understand existing solutions, and easy to modify existing solutions. These translate directly into agility for the business.
For the computer, convenience means that the solutions are easy to run. That usually means they don't make any Big-O complexity mistakes like searching through a linear sequence of length n, n times. That would be a quadratic algorithm and wouldn't scale well. But it can happen accidentally if you're composing opaque operations. We want to anticipate and avoid those accidents if possible.
So what's the problem?
Who wouldn't want easy to write, read, and maintain, with efficient implementations? Why is this even a problem?
The reason this sits wrong with me is that programmers tend to optimize prematurely. Convenience is an important factor, but it should come very late in the process after much of the model has been fleshed out. In the first phase, simplicity and correctness should be the only concerns. Only after simplicity and correctness are guaranteed should we think about how to implement it.
Well, that leads to a new question: How do we guarantee simplicity and correctness? That's what we'll deal with next time.
Programming Media 🍿
Strange Loop videos are out! I couldn't make it this year, but I have been enjoying the talks.
Good movie 🎬
Wow! Who knew the philosophical implications of quantum physics and nuclear weapons could be explored in dialog? This is a TV adaptation of a play, featuring Neils Bohr, Werner Heisenberg, and Magrethe Bohr (his Neils' wife). If you're into the philosophy of science, this is a real treat.
Book update 📘
Grokking Simplicity has been selling well. I'm not doing much to promote it now, so that means word of mouth, which means people like it enough to recommend it! Thank you if you have bought it and/or recommended it. If you're a superfan, please leave a review on Amazon! It really helps people find the book.
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
- Product of digits of sum - Submissions
This week's challenge
Reverse-Polish notation is a way to write mathematical expressions where the operator appears after the operands. For example:
1 2 + => 1 + 2 = 3
In traditional parenthetical notation, that is equivalent to
(1 + 2)
and in Lisp
(+ 1 2). If we assume there are four binary arithmetic
/), we can write arbitrarily complex
expressions with no need for parentheses.
1 2 + 3 + => (1 + 2) + 3 = 6 4 2 * 2 2 + + 8 / => ((4 * 2) + (2 + 2)) / 8 = 2
Your job is to take a string of numbers and operators (all separated by spaces), parse them, and calculate the answer.
(rpol "1") ;=> 1 (rpol "1 2 +") ;=> 3 (rpol "1 2 + 3 +") ;=> 6 (rpol "4 2 * 2 2 + + 8 /") ;=> 2
- All operations are binary.
- There are some cases where there aren't enough arguments. You should throw an exception.
- There are some cases where there are too many arguments. Return the result of the last operation performed.
- Use a stack.
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.