Costume Your Code
Of all holidays, I think I’m least consistent with the degree to which I observe Halloween. I can’t pinpoint any Halloween traditions that I subscribe to on a yearly basis, I don’t have any standing rituals around the day; this is unlike the familiar events that annually mark Christmas, Easter, or even Independence Day. Sure, as a child I would dress up with my brothers and run around the neighborhood in a free-candy induced frenzy; these innocent times were much more “treat” than “trick”. As time advanced I became more exposed to the “scary” side of the holiday, attending haunted houses and watching horror movies with middle and high school friends. College years again saw a variety of observances - dining halls adorned with pumpkins, professors bribing students to attend office hours with free leftover candy, and the requisite not-to-be-discussed shenanigans.
I’ll be the first to admit to being a bit of a wimp when it comes to horror and “scary stuff”. I can handle a bit of suspense, but the jump-scares that dominate most of the Halloween experiences out there have never been very enjoyable for me. I like the lighter, more playful side of the holiday much better: office costume contests, free snacks, and cartoon witches are more my speed. I think that this preference comes down to a desire to understand. I can distinctly remember coming to understand this about myself the hard way: on a middle school church youth group excursion to a “haunted corn maze” I briefly became separated from the group I was with and was alone in the maze; the sense of panic that overcame me at the sound of someone approaching from the darkness left a lasting impression. It was then that I realized that I preferred haunted houses put on by friends to the commercial affairs that I was lost in. I could have fun suspending my disbelief when I had a subconscious understanding that the people behind the masks were the same people that I knew well; once that reassurance was taken away and strangers entered the mix, however, I became much less comfortable with the situation.
I think this speaks to a deeper-seeded realization that what’s truly disturbing, the times that you think “yeah, I’d rather not have been talked into this” are when you’re not entirely certain what’s around the next corner, behind the mask, or under the rock. You’re (understandably) fearing the unknown. Rationally I know that virtually all the folks working your average haunted house are not really out to get me, but what if? I were to encounter the exception to the rule and find that there was one who wanted to do me harm? The thought certainly nagged at me that night in the corn maze and has soured my opinion of such celebrations of All-Hallows Eve ever since.
This fear of the unknown is primal, hearkening back to a time when danger truly was around any corner and our human survival depended on being prepared for anything. If, however, we had assurance that there was nothing lurking in the shadows (or if the lurker were a buddy looking to get nothing more from us than a good reaction) we would be able to move forward more quickly, with greater confidence, and (if you’re similarly adverse to the frightful) enjoy the experience. How might we have such an assurance? Off the top of my head I immediately consider obtaining a map, finding companions with which to navigate the treacherous road ahead, and maybe even donning a costume of our own so as to render ourselves on equal footing with the monsters.
As usual on this blog, I’ve found that this is a nice metaphor for how we ought to navigate code: that the ghouls and goblins hidden on the side of the path are much less intimidating when we’re prepared, armed with maps, companions, and costumes.
First: a map. To me the clearest map one can have when approaching a new body of code is found in the module structure. Proper module breakdowns help us skip past dead ends, avoid potholes, and find the most efficient route to out destination. Module structure reinforces separation of concerns, much like a map might help us reason about swaths of the world around us.
Even with the best of maps we will sometimes need help orienting ourselves - for this a compass might work, but I’ve never really been much of a navigator: I prefer just asking for directions. Luckily most code comes with a welcoming group of traveling companions (aka co-workers/teammates) who are usually happy to point you in the right direction. I’ve been blessed these past few months to have an extraordinarily supportive team guiding me as I explore the twists and turns of the new code that I get to work with at Robinhood, I’m constantly having to remind myself that asking questions and getting my orientation from these mentors not only benefits me but is often a boon to the guide as well; the saying that you never really understand something until you can teach it rings true.
If we are to confront the scariest of monsters in the corn maze of code, we’ll need to arm ourselves with some of the most powerful tools available to developers today: abstraction. Think about it like putting a costume on your code - the costume seeks to misdirect, to hide your true nature and give you some sort of advantage. Good examples of misdirection in code that come to mind include the repository pattern and database abstraction layers (Room on Android, for instance); this idea could even be applied to the larger principle of dependency injection in object oriented programming as provided by tools like dagger, hilt, and Koin. Care must be taken when applying a costume to code: too much costuming and there is a chance that future developers will struggle to see past the mirage and will not be as aware as they should be of the intricacies of the system underneath. This often rears it’s head when considering multithreading and parallel programming. We would prefer to avoid having to manage all the complexities of synchronizing multiple processes, but cannot become blind to the dangers that can arise from parallel execution; a balance between usability and control is critical. Preserving the ability to lift the veil on abstraction ensures that developers downstream can leverage our layers of abstraction without being trapped in a frustrating “black box” situation.
Next time you find yourself in a spooky situation in your codebase be sure to arm yourself against the flying purple people eaters with a good set of directions, some brave traveling companions, and a mirage of your own; you’ll find the adventure out of the labyrinth to be easier and more enjoyable.