PurelyFunctional.tv Newsletter 437: To build or not to build, that is the question
Design idea 💡
To build or not to build, that is the question
In programming there is a wide-spread 1st order theory that one shouldn't build one's own tools, languages, and especially operating systems. This is true---an incredible amount of time and energy has gone down these ratholes. On the 2nd hand, if you can build your own tools, languages and operating systems, then you absolutely should because the leverage that can be obtained (and often the time not wasted in trying to fix other people's not quite right tools) can be incredible.
It's a great quote that illustrates an idea I think about often (and have explored in this newsletter before). How many of us have debated with ourselves about whether to build a solution ourselves or to use an off-the-shelf solution?
I think many people choose to focus on speed of early delivery because it stops the debate. If you need to release something soon, you don't have time to develop your own tools. And then, by the time you are successful (if you are successful), it will be too late to start over.
But if you can take your time on the first releases, building your own tools will increase your velocity in the long term.
Since both theories are true, I suggest that navigating which things to build yourself and which to use off-the-shelf is one of the key skills we need to develop. For instance, ClojureScript is built on top of the Closure Compiler, which the maintainers still agree was the right decision.
Building it yourself has a danger: you can fall down the ratholes. How can we avoid those?
Alan Kay gives a hint in the same essay:
Instead of trying to build the complex artifacts from scratch---like trying to build living things cell by cell---many of the most important projects built a kernel that could grow the artifact as new knowledge was gained---that is: get one cell's DNA in good shape and let it help grow the whole system.
That is, don't build the whole system. Build a kernel that can grow.
A kernel is intellectually manageable. It can fit in your head, and you can get it right. And if the kernel is good, it can give incredible leverage. If you get the size to leverage ratio right, your system can be much simpler than you thought you needed.
David Nolen talks about this in his talk. After demoing the live coding ClojureScripters can do in React Native on a phone or phone simulator, he talks about how simple the solution is:
We're not using any frameworks. No routing. We've done no setup. The reason the code is so small: We have no dependencies. The demo that you saw was just functions. It can only happen because of the simple programming model and the way that ClojureScript works.
It is really hard to explain why REPL-Driven Development is different from having a JS console in your browser. It is hard to explain why live coding isn't just a feature of some extensive framework. What makes it different is that the whole system is built on that little kernel: the Read-Eval-Print-Loop.
There is another hint in Kay's paper:
[Butler Lampson] called for two general principles: that we should not make anything that was not engineered for 100 users, and we should all have to use our creations as our main computing systems (later called Living Lab). Naturally we fought him for a short while, thinking that the extra engineering would really slow things down, but we finally gave in to his brilliance and will. The scare of 100 users and having to use our own stuff got everyone to put a lot more thought early on before starting to crab together a demo. The result was almost miraculous. Many of the most important projects got to a stable, usable, and user-testable place a year or more earlier than our optimistic estimates.
- dogfood your prototype computer instead of using a working, existing computer
- take more time before you code instead of getting something working
- do better engineering instead of taking shortcuts
Those three things resulted in faster medium-term delivery and more useful systems.
Of course, they didn't build everything. They certainly weren't sewing their clothes or grinding lenses for their eyeglasses. There must be some discriminating choice as to how much you build yourself. But I think it's further than we tend to think in the industry.
Make a simple kernel. Dogfood it. Engineer it well. Pick which tools to buy and which to build. And see where it takes you.
Awesome book 📖
Project to Product by Mik Kersten.
I've been enjoying this book because I find it comforting that people are figuring out what is wrong with software development (especially at large companies) and how we can fix it. While the writing feels repetitive, the content is good.
The premise is that software is managed like a project, meaning there is a budget and a deadline. When you have a project, managers think about controlling the cost and delivering on time. However, we should think about them as products where design, implementation, and delivery work hand-in-hand to deliver business value. The book goes into great detail. I highly recommend it. It shares many interesting insights from industry studies. It also contrasts software development with manufacturing (from which many of our analogies and "Agile" practices derive).
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 sk ills. 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
Phone to letter translation
Phone keypads and rotary dials have little letters on them. Most numbers translate into letters. Of course, with only 10 digits, but 26 letters, there is a problem: the translation from letters to numbers is lossy. When translating from numbers to letters, there is always more than one possible interpretation.
Write a function that takes a string of digits and returns a collection of the possible strings of letters it corresponds to.
(digits->letters "22") ;=> ["aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc"]
Here are the mappings you should use:
1: no letters 2: abc 3: def 4: ghi 5: jkl 6: mno 7: pqrs 8: tuv 9: wxyz 0: space
If a character appears in the input that does not have a mapping, it will appear in the output untranslated.
Please submit your solutions as comments on this gist.