PurelyFunctional.tv Newsletter 401: design is not about ease of change
From OO to Clojure Workshop!
Watch my free workshop to help you learn Clojure faster and shift your paradigm to functional.
we really care about design
I got a flood of responses to my last newsletter where I asked whether business values software design. I'll summarize it.
Many people talked about design having a ton of value, depending on the phase of life of the software. For instance, in an early startup, speed might be more valuable than design, whereas with established software, good design is what keeps the speed high over time. But still no one reached out to say "our team has a design budget." Or "we spend $Xk on design consultants per year." It seems like programmers value design, mostly as a quality-of-life issue, that they address through education, like reading books and experimenting. Finally, design is part of the holistic process of building software, and experience plays a big role in understanding how much design should be applied. It needs to be balanced against the other forces in the system.
I'm still wrestling with the idea. Still skeptical.
Clojure Tip 💡
design is not about ease of change
This week, I'd like to talk about the return on investment (ROI) of software design. But first, a brief digression into the ROI of business.
If you know that people in your village don't have enough mustard, you might smell a business opportunity. You could travel to another village, where they have too much mustard, buy a lot of it, then ship it back to your village. You sell it for a great profit. That's called arbitrage, and it forms the basis of commodity commerce. You make a trade, you earn a lump of cash.
The ROI of that trade is easy to calculate. It's easy to explain why you did it: for the profit. But imagine this becomes your career. You're a spice trader. Over the years, other people figure out what you're doing and they start to compete with you. Your business becomes more complex. It's not longer a simple buy-low-sell-high game. Instead, it's a sophisticated strategy in the marketplace. If I were to ask you what your business was about after 20 years, whereas at first you said "profit", now you talk about intangibles like trust, quality, reputation, relationships, customer service.
The spices and the money, the physical transactions that take place, these are secondary to the longer-term considerations. Profit directly comes from the transaction, but it couldn't exist without the long term intangibles. Further, direct pursuit of profit may undermine the strategy. This problem is known as a quick buck.
When asked to define the ROI or even the purpose of software design, many people will say "to make change easier" or "to lower the cost of maintenance". I think those make just as much sense as saying spice trading is about profit. Of course, a one-time design choice is about a tangible improvement. But stretched out over time, the explanation is inadequate. Short-term thinking about "making change easier" is the software design equivalent of a quick buck.
There is some intangible to software design, like reputation in business, that forms a long term strategy. That strategy, over time, allows the ROI to continue. Yes, your software will be easier to change. But you can't try to get it directly. I have been calling that intangible truth (but I know it's a loaded term). It's the thing you can directly target to improve the design of your software over the long term.
So what is truth? Our software is a description, in a very technical language, of some small part of the world. How well does it describe that part? Does it catch the subtle, yet relevant, nuances? Are there things the software describes that don't exist? In other words, how closely does the software description fit the relevant part of the world?
Of course, you can't model the whole world in all its detail. You must choose a small domain and you must ignore the right details. Software with maximum truth would allow you to represent exactly the relevant details of the domain and no more. This will probably raise the hairs of people traumatized by "big, up front design". However, this is a goal over the horizon that is constantly moving. And you never get there. The particular domain and details are always changing. Plus, we often learn the relevant details through writing the software. We'll talk more about that next time.
But I'm making a really strong assertion: pursuing truth will, in the long run, maximize ROI. Having a better description of your domain's relevant details leads to software that is easier to change. I'll be exploring that assertion in this newsletter, my podcast, and my blog. And maybe in the book that is still an embryo right now. I'm sure I don't have it all organized and even correct yet.
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. Stay at home. Wear a mask. Take care of loved ones.
Clojure Challenge 🤔
Last week's challenge
- RGB color mixing - 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
Sums of pairs
Write a function that takes a collection of numbers and a target number. Return all pairs of numbers found in the collection that sum up to the target number.
(sums-of-pairs [2 4 5 6] 8) ;=> [[2 6]] (sums-of-pairs [3 2 0 1 1 5] 5) ;=> [[2 3] [0 5]] (sums-of-pairs [1 3 2 3 4 5] 7) ;=> [[3 4] [3 4]]
- There can be duplicate numbers and hence duplicate pairs.
- Each pair should be sorted.
Please submit your solutions as comments to this gist. Discussion is welcome.