PurelyFunctional.tv Newsletter 410: don't encode your policy
From OO to Clojure Workshop!
Watch my free workshop to help you learn Clojure faster and shift your paradigm to functional.
Design Tip 💡
don't encode your policy
After I published the timeless in an unstable domain, generous reader Tim Cross shared his experience with me. I'll quote him (with permission):
One of the first 'rules' I learned and often one of the first things I would tell a client is "Don't incorporate policy into your model. Instead, incorporate functionality in your model which will facilitate the businesses ability to monitor and enforce policy compliance."
This is precisely in line with your point about timeless truth and knowledge of a domain. Business policy often changes much faster than software.
Policy can change at the wave of a senior executives hand. It doesn't actually represent truth about your domain, only a snapshot of a type of state at a particular moment.
This really resonated with me. And I think it applies not just to fast-changing business rules, but also to the ability of your software to be useful in the many gray areas that exist in the real world.
I was working for a company that did electronic signatures (like Docusign). One of the laws in the company's country of origin was a kind of "no take-backs" rule. If I send you a contract to sign, I can't later take it back. Sending it to you represents my agreement to the terms. We baked that law into our code. In our system, you could cancel a document before you send it, but not after.
Well, we got a lot of requests from users to be able to cancel the document. "No, no," we said, "the law says you can't, so we don't allow it." But people still wanted to. Were they criminals? No! When we dove deeper into the idea, we realized it was all legit.
Our users were sending a contract, then the recipient would ask for a change to the wording. So our users wanted to cancel the original and send a new one. There was nothing wrong with that, since they both agreed.
Our desire to enforce the law was getting in the way of a legitimate workflow. We removed the limitation and things went much smoother. But we weren't blocking bad contract behavior. Isn't that bad?
Well, that's not really our job. That's for the courts to handle. A "canceled" flag in our database wouldn't prevent someone from breaking the terms of the contract and the ensuing legal battle.
That job taught me a lot about software interfacing with the law. We had to roll back many encoded rules based on laws. Here's another one:
A contract is an agreement between two or more people. FALSE! There are contracts with only one signatory, such as a terms of service agreement. We had to separate out the authoring and sending of the document from the signing flow. That is, the sender might not sign the document.
All of these discoveries in our domain made our model better. We were getting at deeper truths in the domain. Over time, we turned it into a powerful platform because we saw past the letter of the law into the deeper, richer ideas in it.
React Survey 📋
React has changed web development. It is now the most popular font-end framework. I started using React in 2013 (!!!) and it has made my ClojureScript development much easier. React solves a very precise problem in the browser: How do you keep the DOM in sync with your state?
When I venture outside of the ClojureScript world, I am more than a little shocked. React is being used, but not to solve that very specific problem, but to solve every problem. It seems like a place ripe for rationalization. And I'd like to help.
I am here to listen to your problems! If you use React in any form, please fill out this survey. My hope is that you will fill it out with your own personal troubles, complaints, and frustrations.
This morning, I published a new podcast episode. I'm going to be going through all of the Turing Award Lectures, starting in 1966. The first award went to Alan Perlis. You can listen to my excerpts and comments here.
Book update ✍️
The other day, my wife asked me if my book was on Amazon. I did a search, and indeed it is! It is available for pre-order.
However, you should probably buy it on Manning's site. You can buy Grokking Simplicity and use the coupon code TSSIMPLICITY for 50% off. You can buy it now and it will be shipped to you when it's printed. Meanwhile, you can read the PDF version today!
Also, just a heads up: both Manning's site and Amazon show that the book is estimated to be 350 pages. Well, it's already written and it's 550 pages! I've let them know so it should be corrected soon.
And don't forget about the forewords by Jessi Kerr and Guy Steele 😀
Thanks to those of you who have already purchased 😘
ClojureScript course 🎓
Chris Oakman is running a 3-month ClojureScript course this February. He's got lots of teaching experience and he designed the ClojureScript logo (among many other achievements). If you're itching to learn ClojureScript, this is a good opportunity.
Quarantine 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.
Also, if you just want to subscribe for a paid membership, I have opened them back up for the moment. Register here.
Stay healthy. Wash your hands. Wear a mask. Take care of loved ones.
Clojure Challenge 🤔
Last issue's challenge
- First before second - submissions
Please do participate in the discussion at the submission links above. It's active and it's a great way to get comments on your code.
This week's challenge
Write a function that nests the elements of a list one level deeper by repeating that element inside a new list a given number of times.
(nest [:a :b :c] 2) ;=> ((:a :a) (:b :b) (:c :c)) (nest  10) ;=> () (nest [1 2 3 4] 1) ;=> ((1) (2) (3) (4)) (nest [1 2 3] 0) ;=> (()()())
Thanks to this site for the challenge idea where it is considered Hard in Java.
Please submit your design process as comments to this gist. Discussion is welcome.