Many thanks to Tess Huelskamp for reviewing and editing this before publication so that my many errors and structural oddities don’t have to be endured by others.r />
Because I believe in being transparent, wearing my heart on my sleeve, and failing publicly, (and for my own selfish desire for catharsis), I’m going to tell you about how I badly handled departing a software project. I didn’t follow through on promises, give good feedback, or leave a project in a state fit to be picked up by someone else, but I did my best impression of disappearing in a puff of smoke and hoping nobody would notice.
🔗 The Setup
For those of you who aren’t familiar, the Pepper Project was an idea by the professor in the lab I worked in as an undergraduate whereby you could include Python in the preprocessing directives of a piece of C or C++ code and have the Python interface with the symbol table and the preprocessor itself. This would serve to augment–or replace–the macro language, allow loading of config files (primarily made up of constants) at compile time, and other crazy behaviors. The professor was super enthusiastic about this idea, but was swamped with his other responsibilities, and I was itching for a challenging engineering project, so the project was assigned to me.
We realized, of course, that this would likely require writing a full C preprocessor in Python, but I’d just come out of a compilers course (specifically, “Translation of Programming Languages”), and thought myself hot shit, so writing a preprocessor would probably be time consuming, but not difficult.
Since the professor was largely occupied with the day-to-day of running his lab I would be largely on my own for writing the code and such, which was fine by me. Starting the project is the easy fun thing, right?
🔗 The Problems
For a while, my soloing the project worked fine. I was making progress implementing the spec, the professor had time to run the other parts of the lab, I hadn’t run into anything insurmountable. Things were good. As the project dragged on, and my graduation crept closer, I started losing interest. I was growing frustrated with things:
- The other student contributor who was brought on
- This required better planning of feature addition so we weren’t running into merge conflicts which made me frustrated (since I couldn’t just cowboy some code) and reduced our feature velocity
- They were delayed in giving or taking feedback on PRs, which made it difficult to maintain a good pace. This wasn’t their fault–school and life interfered freely and were a higher priority–but I didn’t have ways to mitigate the scheduling issues those interruptions caused.
- The rats nest of the grammar I’d constructed for the preprocessor. It had grown organically, as I’d discovered bits of the specification we hadn’t accounted for, and so I tacked things on. But it was difficult to understand, difficult to test, and impossible to easily modify as we discovered issues that ran deep in the grammar design.
- The lack of easy returns from the project; since it was such an all-or-nothing kind of program it was hard to tell when we’d successfully completed a feature, or if we were even on the right track in terms of overall design. I was sure we’d discover hundreds of bugs when we were finally able to actually grammatically handle the standard library.
All these were very frustrating problems–That I never reached out for help with. My frustrations with the other student were silent, I never really sought out help in figuring out the grammar design, and while I’m sure now there were better ways to design the project so it could be testable I never did that either. I feel now that if I’d had a mentor on the project, at least to make sure I was heading in the right direction or that I had a place to at least vent my frustrations, the project would have ended in a much better state than it did–but of course, I didn’t bring that up to anyone either.
There’s a few reasons why I kept it to myself.
- Pride. I wanted to handle these things myself, to show that I could and because I wanted to ‘own’ the project. Sure, it was the professor’s idea, but darn it, I was going to build it and write all the policy around it. I’d sunk so much time in it, I wanted to ‘protect’ the stake that I had.
- I thought I was doing others’ a favor by not adding my problems and frustrations to whatever they were already dealing with. Since I had no obviously assigned mentor, and taking these relatively small issues to the professor when they were already tremendously busy seemed silly, I felt that it would be an inconvenience to others and that I’d be skirting my responsibility by not just Figuring It Out .
- I had other things that were competing for my interest. There was a local security startup that I wanted to part-time at, to get a feel for what security work would be like. I wanted to spend some time enjoying post-graduation freedom before I started full time–The Pepper Project, due to its frustrations, had fallen down my list of interests to rest comfortably at the bottom.
There’s some of these issues that I feel exist in part because of how the lab was structured, but that isn’t an excuse for my not handling them. By ignoring the problems instead of voicing them to anyone in the lab, or making sure that the next person on the project wouldn’t run into the same issues, or that people at least knew the state of the code.
I didn’t make sure those things happened–which was my responsibility as the maintainer of the project. Instead, I made a quiet exit stage-left, and let Pepper sit and collect dust.
🔗 What now?
I firmly believe failure is a learning experience. Negative feelings—pain, anger, shame, frustration—are all indicators that something can be improved.
Clearly a lot could be improved here.
Be Vocal, Yet Civil, About Being Frustrated
This is something I’ve picked up from my manager in industry: making sure people know that some part of a process, or communication, is frustrating you is helpful as long as you’re civil about it. If you’re silent, then nobody knows that something should be fixed, and you just stew in your own annoyance until it boils over. Fear, uncertainty, and doubt are real threats to mental and emotional stability, but addressing them helps.
Manage Expectations Carefully
This is something I did terribly on the Pepper project, and is something that’s at the heart of Agile and good project management skills. Managing people’s expectations of your ability to get work done, and managing your own expectations of how much you can get done, helps tremendously with preventing the frustrations from even happening in the first place. If you say “Sure, I can try to get the rewrite done before I leave, but that’s a lot to do and I’m only one person, so I can’t guarantee it” is much more helpful than “Yeah, I’m sure it’ll get done” while harboring doubts and then eventually leaving. This one is especially tricky because nobody wants to be the bet-hedger, or the one dragging down the project velocity, but it’s so much better to be conservative in your estimates than to have to scramble later.
Code For The Future Maintainer, and Remember You’re Temporary
Code doesn’t exist in a vacuum, and mental state is transient. The future maintainer might be you, who may remember the various gotcha’s and hacks in the codebase as you tried to solve the problem in the first pass, or it might be someone who isn’t even familiar with the problem your program is trying to solve. Code for that person.  More than that, remember that you won’t always be on the project, so make sure there’s a way to hand off responsibility for that. Plan for that handoff long before it happens, too, so it isn’t rushed, awkward, or entirely absent. Planning ahead makes it easier to make sure you haven’t forgotten anything, and that the recipient of the responsibility isn’t surprised by the current state of the project or something you forgot to mention.
Make Sure You Have Someone For Guidance, Technical or Otherwise
Second opinions—opposing or otherwise—do wonders for helping our understanding of a problem. Having that person pointed out makes it easier to come to them with problems and to not feel like I’m burdening an already-busy coworker or awkwardly shifting my problem onto someone else. Even if that person can’t offer a solution directly, but can point me to where I can find one, it’s significantly better than winging a technical solution on my own (which is how you get “organically” grown code). This would have helped me greatly with spinning my mental wheels on grammar design, or on how to manage multiple people on a project.
🔗 What’s the point of this?
Some (a lot) of this post is selfish. The way I departed the project—silently, without a handoff, after failing to meet a promised goal—has been bothering me for a while now. So some of this is me searching for catharsis.
This is also an attempt to fail publicly. I think it helps the community tremendously when people aren’t afraid to admit when they screwed up, and to share what they learned from the experience. 
More importantly, I want to welcome criticisms, suggestions, and thoughts. Also, with some luck I can prevent a fellow developer from falling into similar problems.
This is something that I’ve felt is radically different in every other development environment I’ve been in. While in the lab everyone shared their research, problems they were having with their data, collaborating on paper writing–The programming side felt remarkably siloed. I rarely saw people collaborating directly on a piece of code, either through pair programming or code reviews. We all worked in the same library, but usually adding separate features that someone else would use later. Issues were shared, but actual development seemed to be a very individual process. This was so different from other programming environments I’d worked in–including another lab–that it felt very strange to me to reach out for actual programming help within the lab. ↩
Documentation, up to date variable names, making sure your evil dirty hacks are obvious and not going to trip someone up, keeping an up-to-date roadmap… I could go on, but that’s out of scope for this post. I’ll either write one later on this topic, or you can find a post by someone both more experienced and more eloquent than myself. ↩
I think this is actually a significant issue within our entire industry, and why we struggle so badly with things like security breaches. We’re really unwilling to admit when we (as developers, or software companies, or people, etc) made serious mistakes, and so we haven’t developed ways to deal with those mistakes. With other engineering disasters—the Tacoma Narrows bridge, every aviation failure since the inception of the FAA, the Gulf oil spill—there’s investigations, fact finding, analysis to determine what contributed to the cause, and, eventually, change. Until we, as an industry, are willing for our failures to be seen by the public, be they big or small failures, we will not deserve trust. But that’s an entire blog post on its own. ↩