No new screencasts to show this week. I’m in the middle of doing some much-needed refactoring. What happened? As of the last update, I had a decent expression editor. The missing final piece was adding a declaration layer to the editor, allowing a Unison panel to be edited much like a module in a regular programming language.
Unfortunately, when I started working on this, I found I just couldn’t take another step. All the crappy Elm code I’d written out of a singleminded desire to maintain velocity, velocity, velocity, had finally caught up to me. I’d been ignoring what turned out to be some bad architecture choices I’d made early on and the code was getting uglier and uglier with each feature I added (never a good sign). The thought of adding yet more ugly code to the pile seemed pointless and unmotivating. It was time to pay down the technical debt.
So I’m currently in the process of rewriting parts of the editor. I’ve discovered a nicer way of organizing my Elm code that avoids some of the problems with the Elm architecture. I’ll write that up in detail in a separate post.
There’s also one other thing I have planned which is to change the language representation to use abstract binding trees (ABTs). At the moment, the Unison language has only one binding form, lambda, and I am using manual (untyped) De Bruijn indices. Besides being error prone (I have to remember to weaken variables in all the right places), this doesn’t scale very well to adding other forms of binding like pattern matching and let bindings. ABTs scale well to arbitrary binding forms, and for my use case they are a better fit than a bound-like approach. I’ll also try to do a writeup of this at some point.
Until then, there probably won’t be much (visible) progress, but I hope to have some more interesting updates in a couple weeks.
This all got me thinking a bit more about the concept of technical debt. Given the choice of paying back technical debt or adding more features and functionality, which makes the most sense? That depends. In paying back debt, you (definitely) lose some velocity in the short term in exchange for an (uncertain, but presumed) longer-term increase in velocity when the code is in better shape. In effect, you are making an investment in future productivity. Whether this investment is rational very much depends on the time value of the new functionality, one’s risk tolerance, and on the expected likelihood that the refactoring will indeed increase future productivity. Best to illustrate with some examples:
Of course, the people making decisions about these things aren’t usually so rational about it. But it’s always good to have a decisionmaking framework that lets you explore aspects of a decision in a more methodical way.
… except it’s not that simple. There’s one factor I’ve completely ignored, and that is programmer motivation. Working on code you know is shitty is demoralizing. I would say that different programmers can tolerate different amounts of technical debt before it substantially affects motivation, but it is definitely true that working on high-quality code is exciting and empowering.
Pretending that engineers are emotionless machine parts that operate with the same efficiency no matter where they are plugged in doesn’t change the reality that programmers are human beings. Even if we were purely interested in the productivity of the overall business, decisions must factor in the happiness and motivation of the people doing the work. When you factor this in, the full costs of accumulating technical debt become more apparent:
Also see I hate type errors!, which talks more about programmer motivation.comments powered by Disqus