PurelyFunctional.tv Newsletter 386: factoring equations in code
Sign up for weekly Clojure tips, software design, and a Clojure coding challenge.
Clojure Tip 💡
factoring equations in code
Once in college we had to write a simple function that computed a simple formula. I don't remember exactly what it was, but it was something like this:
2x + 2 y + z
Now, being 18 and wanting to impress the teacher (and having read too many books on how to optimize video game code), I got clever and factored out the 2.
2(x + y) + z
Notice that there is now only one multiplication instead of two! I could save a whole instruction each time this was called!
In those days we printed our code listings out on wide, green dot matrix paper. I handed mine in and waited for my excellent grade.
But the teacher marked it wrong. I went to talk to him about it. I showed him that it was the same formula. That it got the right answer. But he said something I still remember: "That wasn't part of the spec. Don't go above and beyond." He did give me my points back, but the lesson stuck with me.
I still don't know if he was right. Is it important that it worked? Was the readability impacted that much by my small factoring? What if I had found a way to do something in constant time that, as expressed in the problem, took quadratic time? Wouldn't that be a worthwhile improvement? Where do you draw the line between saving a multiply and improving the complexity?
Or was I just caught in his pedagogical style, where he wants the code listings to be easy to read so he can grade them quickly? Or, to be generous, to guide me on a journey of discovery with a known destination---don't stray too far from the path or you may not discover what he wants you to.
Anyway, I'm still thinking about it, and I was reminded of it in last week's challenge. The quadratic formula is well known. You can find its common expression with a google search. We even had to recite it in school so we would remember it.
But when I went to implement it as code, part of me really wanted to refactor it. I resisted, though I did name the parts. The formula is still intact. Others, however, didn't resist. There are some really interesting factorings of the formula. And I'm torn.
The factorings achieve some neat properties. No conditionals! Reuse of calculated parts. Even some interesting symmetries that require study.
But the factorings also obscure the traditional expression of the formula. If I look at one of the more factored versions, I can't tell if it is correct. I can't see the original formula in there without breaking out a paper and pencil and un-factoring it back. Although the solution is elegant, I wonder if something important is lost.
All this is to say that, as I read the submissions, I feel for my professor from 20+ years ago. Even when I look at my solution, it feels too clever. I wish it had been a straightforward implementation of the formula.
Don't get me wrong. Exploration is great. But when you check in your final version to git, your solution doesn't have to be the furthest out you reached. Maybe you go exploring and find out the best place is just where you started.
My new episode about the classic paper Why Functional Programming Matters by John Hughes is out. In it, we try to understand this paper's answer to the question of why functional programming is powerful.
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.
Stay healthy. Wash your hands. Stay at home. Wear a mask. Take care of loved ones.
Clojure Challenge 🤔
Last week's challenge
Very nice variety of answers in this one.
Please do participate in the discussion on the gist where the submissions are hosted. It's active and it's a great way to get comments on your code.
This week's challenge
indices of a value
Let's say you've got a sequence,
[:a 1 :d :f :r 4 :d] and you want
to find all of the indices where
:d is. That would be
(2 6). Your
task is to write that function:
(indices-of :d [:a 1 :d :f :r 4 :d]) ;=> (2 6)
Thanks to this site for the challenge idea where it is considered Medium level in Python.
You can also find these same instructions here. I might update them to correct errors and clarify the descriptions. That's also where submissions will be posted. And there's a great discussion!
As usual, please reply to this email and let me know what you tried. I'll collect them up and share them in the next issue. If you don't want me to share your submission, let me know.