Sunday, June 29, 2014

Emotions and Programming

I've always been an emotional coder. For most of my early life, there was one dominant emotion that I experienced while coding: joy. I was that nerdy kid that was excited to get home from school most afternoons because it meant I could fire up my trusty IBM PC XT 486 DX Pentium II computer of the time, open up my beloved GWBASIC Turbo Pascal Borland Pascal vim Emacs editor/IDE of the time, and get back to whatever silly thing I had been working on later the preceding evening than I'd like to admit to my mom.

I'd feel other emotions too, like uncertainty and surprise, but for the most part, I felt joy. At least that's how I remember it. Joy at making something out of nothing; joy at discovering something new; joy at deepening my understanding of some hitherto opaque mystery.

These days, I still get emotional when I write code. My emotions while programming today are a much more mixed bag, though. I still experience a taste of that childhood joy, but it's usually reserved for moments when a particular piece of code just works really well. Other times, I'm typically either stoic about the experience, or I'm feeling some form of frustration.

As far as negative sensations around code go, people talk about code smells, but that's not a good analogy for how I experience it. For me, smell is a sensation that's purely restricted to the physical realm (perhaps owing to my exposure to it as a parent of two children and owner of servant to two dogs). Instead, I typically feel negative emotions related to programming in two ways: as pain in my back and upper shoulders, and as mental discomfort not unlike the experience of cognitive dissonance.

Let me tell you about some of the ways in which I get emotional about code.

Bad tools give me back pain. Literally. If I'm using a tool that's unfamiliar to me yet behaving in an erratic or unintuitive fashion, especially if that tool requires burdensome and unnecessary steps, or responds in a non-deterministic manner, I will eventually get back pain. First, my shoulders and upper back will tense up. Eventually this tension will extend to my lower back, and at that point, I'll start noticing a sharp or dull pain down my back. I try hard to maintain a relatively ergonomic work environment, and most of the time I can be comfortable at my desk for hours, but expose me to the default Windows command prompt window with its insane copy/paste interface, and it won't be long until I feel the manifestation of its crappiness pulsating down my back.

Weird, I know.

There are a few things that give me a sense of frustration similar to what I experience when I'm facing a tough decision and have conflicting opinions bouncing around in my head. One is not knowing exactly what to do next. Most of the time, when I'm coding, I have a pretty good sense of what the next step is that I need to take. Sometimes, though, I don't have enough constraints to make that clear. Or, I haven't made up my mind about some key design decision. Or, I'm struggling to find the right way to bend some particular API to my will. In any of these cases, I'll experience a sense of frustration that lasts until I've sorted out the particular problem.

Another source of frustration is something I seem to have picked up somewhere in my mid twenties: inability to test. If I can't write good, repeatable, automated test cases for something, I get very frustrated and find it incredibly difficult to churn out code. Sometimes I can get over this with the realization that testing something thoroughly and automatedly would just not be worth the effort. Sometimes the code is simple enough, and whatever it's based on is solid enough, that I simply have no concerns about whether it'll work or not. But most of the time, I know I could do better, and I remember all the pain that a lack of testing has cost me in the past, and I just don't feel right until I can bang out a few functional tests.

This becomes especially painful when I'm working on some code that's difficult to test, not because of some inherent reason, but simply because of how it's structured. I don't really buy into the TDD kool-aid wholeheartedly, and I scoff at the overuse of dependency injection and mocking that seems to be so common in some coding cultures, but I sure hate it when I know there's no real reason something can't be tested, and yet I'm prevented from doing so. Hate is a strong word, but it reflects the emotional state I experience when faced with such a situation.

Considering I spent the first 15 years or so of my "coding life" not writing a single test case (forgive me, I was a teenager for most of that time…) this still astounds me a little bit. My best guess is that the experience I gained when first implementing longer-term, commercial, shipping code and all the maintenance nightmares associated with it really stuck with me at a visceral level. Combine that with an instinct to automate all that can be automated and I am where I am today. Even as I'm writing this, I'm feeling mild discomfort at a few pieces of currently maintained code that I know aren't tested as well as they could or should be: a sort of potpourri of back pain, drowsiness, and primal guilt that evokes memories of secretly eating candy before I've had my supper as a five year old when I know I'm not supposed to.

Seriously, what's wrong with me?

Something I contemplate every now and then is whether this emotional attachment to the state of my code, and the process of developing it, is a good thing or a bad thing. Most of the time I've come to the conclusion that, like all emotion, it's probably a good thing as long as it doesn't completely dominate. Emotions help stir action and can be powerful motivators. When they work well, they nudge you in a positive direction. On the other hand, I could certainly use less back pain, and I know my partner would probably appreciate it if I came home not quite as emotionally drained from work more often.

Perhaps the worst disservice I do to myself is sometimes not listening to the emotions that are clearly there. "I've got a deadline to meet", I'll say to myself, as I plow along (un)happily churning out code that I know really should be tested better. I try to convince myself that "it's just work, and I shouldn't really feel strongly about it", stubbornly trying to ignore the very real emotional state that I happen to be in. That, I find, is when I get into trouble — sooner or later I'm staring at the blinking cursor in my editor, wondering how I got to this point, and considering whether Office Space had a point about construction being a much happier line of work than software development. Ignore your emotions, and soon you won't notice they're there anymore, because they have entirely engulfed you.

It's not always like that, though. I've noticed that I only seem to get (negatively) emotional about code that I'm writing to accomplish something. If I'm writing code purely for fun — something exceedingly rare these days with my family life consuming most of my free time — I have none of these qualms. I get most emotional about the code that I'm writing when I'm trying to get somewhere - when the code that still needs to be written merely seems like an obstacle standing in my way. While I find not knowing what to do next frustrating, I also sometimes despise knowing exactly what code needs to be written, feeling almost as if I've lost my sense of free will by being forced by circumstance to churn out the "unavoidable thousand lines of code" needed to solve some problem. Creativity lies somewhere between uncertainty unbound by constraints and exact knowledge of what must occur next. Sometimes, it's a fine line.

That's not to say that writing code for work (or for any set goal other than coding for its own purpose) is always a negative experience. It's just that, when I don't have a particular purpose in mind, I never notice these emotions. More than anything, I think that's probably because I just avoid the stuff that bugs me in the first place when I'm coding for fun.

I have great respect for people who can maintain a Zen-like state of detachment in whatever it is they do, including coding. Detachment can be blissful and highly productive. I also have a great deal of empathy for people for whom coding is a creative, emotional, disturbing, joyful, frustrating, fulfilling experience. I think great talent exist in both camps, and sometimes both extremes are embodied by a single person over time.

I think I'll probably spend the rest of my programming life occasionally perplexed as to how it is that interacting with a machine, writing software in a completely abstract landscape, and something as mundane as testing can have such a strong emotional impact on myself and others in my field. And I expect I will need to learn, over and over again, how to harness those emotions positively. Perhaps most importantly, I'll need to remind myself to recognize them in others despite how clinically technical the act of programming can seem from the outside.

In the meantime, I'll continue to fret about those tests I haven't written. And maybe soon I'll get to write some of them, and the back pain will lessen a little bit.