I have recently started “taking seriously” making coffee. By that, I mean that I have spent a considerable amount of money, time, and effort, learning to brew espresso at home. Rather than bore you with the history, suffice it to say that this has become my latest expensive hobby. I wanted a challenge outside the realm of building software, and I’ve found it.
My current setup includes a Baratza Virtuoso grinder, beans both from Kicking Horse and from Speakeasy Coffee, and the centerpiece, a Rancilio Silvia Pro V3 espresso machine. This machine has the reputation of being a teacher, and I can see why. I have at best a love/hate relationship with Silvia to this point.
Over the winter holidays 2011-2012, Sarah and I stayed with her parents, and so I bought Silvia and shipped it there with the goal of brewing better espresso during our month of down time. I knew I wanted to step up from the department-store brand espresso machine I’d used for a few years, and Silvia seemed a popular and strong choice. I unboxed the machine, pulled a few shots—that’s the lingo, you see—and did not care for the results. The espresso tasted considerably inferior to what I’d managed to brew using my $200 machine. This simply couldn’t happen, and so I did the simplest thing: I read a few dozen articles on the web about taming Silvia.
Talk about complicated! So many variables… beans, grind, tamp, humidity, water temperature, water quality… I didn’t know where to start, so I did the only thing I could: I muddled through until mid-January, boxed Silvia up, went back on tour, and waited until I couuld unite Silvia with the Virtuoso grinder at home. I couldn’t run a real test, after all, until I used the machine in a proper environment, with a high-quality grinder, high-quality beans, and even time and patience to experiment.
Fast forward to the last few days. I have set up my beautiful grinder along side the temperamental Silvia. I feed this system the best water I have, the best beans I have, and I start pulling shots. Dreck. Bitter. I’m pulling shots anywhere from 10 to 18 seconds. Water is channeling through the coffee at breakneck speed, spurting bitter fluid everywhere. Each shot creates a unique, almost artistic mess to clean up. I literally can’t swallow the results. With Sarah waiting for her morning cappuccino, I resign myself to take the best two out of 6-8 mediocre shots, and hope that cinnamon and microfoam milk mask the flavor enough. I don’t feel good about the coffee I make, but Sarah goes along with it kindly enough.
I’m not enjoying this. After reading a few dozen more articles, like this one, I see that in order to get the results I expected, I need to learn a lot more about making coffee than I already had done, and I thought I’d learned a lot already! I’d read The Joy of Coffee over ten years ago. I seemed to know more than most people around me about making good coffee. I owned an Aeropress! Surely, I knew what I was doing. Apparently not. It seems that, no matter how much I think I know about brewing beautiful espresso, there remains entire worlds I haven’t explored yet. I wanted to enjoy this, but it had become a battle, and I don’t know whether I want to learn all this arcane technical stuff just to make good espresso. The results from my $200 machine seemed like an acceptable compromise by this point.
I know—so far, this has nothing to do with software development.
Gil Broza decided to have a little fun at my expense.
Now, this has something to do with software development.
This entire experience reminded me of the battles we face working in legacy code. We don’t know precisely what the system does, though we have a rough working knowledge of how it works and what it’s supposed to do. We only have one form of reliable feedback: the end result. We might have the chance to check a few intermediate steps in the process—I can roughly check the temperature of the water, the color and shape of the flowing coffee, the time to pour 2.5 ounces of espresso, and how much splatters out from my naked portafilter—but that feedback is inexact, like how wet or dry the puck of grounds feels after pulling the shot, or how much crema I find on top of the espresso. These forms of feedback tell me when I’ve got it all wrong, but don’t help me know when I’ve got it right. I can pull a 23-second shot of 2.5 ounces with a nice dark color and a healthy crema on top, then taste unrepentant bitterness in the shot. Unusable—but everything looked right! What the hell am I doing wrong?!
I really have only two choices: give up, or learn more. In my case, giving up means walking down to Samuel’s coffee house and paying $3-4 per cappuccino. This usually gives me the quality results I want, but at a premium, and comes with one considerable downside: I have to put on pants and go outside. When working with legacy code, giving up means neither replacing nor rescuing the legacy code, but simply living with it, learning to adjust my expectations to its quirky behavior, figuring out how to get it mostly out of my way, but with one considerable downside: when push comes to shove, I can’t change it, so I have to waste time and effort working around it, rather than making it better. Legacy code has a way of creating a vortex of mediocrity around it, sucking in otherwise good code and diligent programmers. We bear both visible and invisible costs, and they seem unbounded. It never ends, and we can do nothing to stop it.
A little dramatic, perhaps, but I think you’d agree, not entirely unrealistic.
For my part, I won’t give up the search for a great espresso. I won’t let Silvia beat me. I will do the research, put in the practice, and figure out how to get consistent, delicious results. I have done it before, and I will do it again. I will have to read a lot of articles, try a bunch of strange-sounding techniques, run through a lot of beans that deserve better treatment than I’m likely to give them, and drink an unfortunate number of mediocre cappuccinos before I get there, but I shall get there. It will happen, because I believe I can learn to do it, I believe I will to learn to do it, and dammit, I want great cappuccino at home.
It’s now late 2015. I have a new grinder, but the same old Silvia, and now pull better cappuccinos than I used to. All the same, I don’t really understand how it all works, I can’t really diagnose problems, when the humidity changes I have to adjust my grind, and if I don’t follow the same ritual very closely, then I don’t get the same results. It all feels quite fragile. I can live with it, because I get a lot of value from the cappuccinos, but it just doesn’t feel comfortable. So it goes with legacy code. I really wish I could refactor my espresso machine comfortably.
I could add a PID, which helps regulate water temperature, but I’m really afraid that installing one will cause me to destroy the machine, so I’ll wait until I can justify investing in a new one. I’ll add a PID, I’ll be able to better regular water temperature, and everything will be better? (Sound familiar? We’ll hire a new CTO, throw it all away, do it in Python, and we won’t make the same mistakes this time. Sure.)