The machine won’t. But maybe I can.
It’s February 2016 and I’m running like two minutes late. The train’s scheduled to arrive in two minutes. I hustle into the station. I tap my card at the turnstile.
Red. Insufficient. Shit.
I dart to the machine, tap card to reader, agonize for 1.5 seconds. The machine is so fucking slow.
Finally, the menu screen. Balance negative $1.75, thanks, I’d figured.
Ok, scan the screen, find the button. I was hurrying the last three times I had to do this, so it takes another precious second to spot it. Add value. Five bucks – crap, no, that’s too low, and it’s too late to go back now.
So I mash the up arrow a bunch of times until it’s $20ish, then watch in horror as the machine – so fucking slow – continues to tally the output of my queued button presses in fits and starts.
$34. Fuck it. Close enough. I glance at the sign, at some point it’s switched from 2 min to Due.
But I’ve got it from here. I’ve memorized this part. I can do it really fast. The letter I is debit. Press as you stage the card for a quick insert in a half second. Boom, screen changes right on time. Card in at that exact moment, card out at the exact moment the prompt switches, bang bang bang bang hit ENTER on the PIN pad, and holy shit the transaction could not be processed.
I was too quick on the card removal. Or maybe one of the pad presses didn’t register and I submitted a three-digit pin, I wouldn’t know, I’d been moving too fast to look up and count asterisks on the screen. No time to reflect, though, the train’s headlights are peeking over the horizon and I have to do this all over again.
Add transit value. This time, I just hit the $20. No need to button mash the number upwards, and anyway I’ll just get a pass next week when the money runs out.
Dimly, grimly, I become aware that I should have just picked a pass from the start.
But it’s too late to go back now. The train is slowing into the station. Debit, wait, card in, wait, card out.
One of the buttons for my PIN is sticky. It takes about a second to notice this, plus one to jam on it hard enough to get output, plus five to clear the accidental extra presses, get it right, hit ENTER.
During the next two seconds, while the order finishes processing, the *DOORS CLOSING** bells sound and I realize I’m now going to be fifteen minutes late.
Receipt Desired? Oh, who gives a shit. No, I guess. I’d prefer not to remember this.
Bears. Beets. Banes of my existence.
My debugging process is like this sometimes.
I start out feeling like I’m already running late. I convince myself that I should have started this task as a smarter person, or a better-prepared person, or a more emotionally resilient person.
And then I project my inadequacies onto two ever-present and crystal-clear mental images.
There’s Best Possible Me, who exercised and meditated this morning before reading 200 lines of production code over a balanced breakfast, and who has likely already finished whatever thing I’ve yet to start.
And then there’s Shittiest Possible Me, who never does anything right and is going to fuck this whole thing up and get called out for it and spiral into a deep depression and probably, I don’t know, cause some dozen faceless strangers to fail at life through some act of criminally negligent remissness that will absolutely happen in the future, all because Real Life Me can’t get his shit together and code this code.
There are several things wrong with this line of thinking, like the fact that neither Best Possible Me or Shittiest Possible Me are real people.
But the fatal glitch in my code happens one step earlier, right before I conjure my angel/devil duo, at the moment I start my work anxious about and fixated on this idea of whom I should be by now.
That’s an expectation. “Expectation” is a hilarious word, and I’m using “hilarious” in the literal, eponymous-Louis-CK-standup-bit sense: so funny it causes you to lose your sanity.
“Expectation” is a hilarious word, and it’s so funny because, in real life as we live it, it means the same thing as “assumption”. Or “dream”.
An expectation is an idea your mind has about how things ought to be at some moment in time. That’s it.
Not all ideas are realistic. Not all expectations can become real.
But our typical usage of the word carries this implicit notion that an expectation must become reality; if it couldn’t, why would we expect it?
And when a given expectation – “I should have started this task as a better-prepared human being” – could only ever become reality if I happen to own a time machine, and I don’t immediately recognize this and adjust my expectations accordingly, then whatever I do to serve that expectation from this point forward is going to chip away at my sanity.
If I’m running late, I’m running late. If I’m underprepared, I’m underprepared. And if I’m wasting brain cycles trying to impose some expectation – some dream – on that unflinching reality, it’s that much harder for me to interface with my waking world in a way that will turn me into a quicker or more prepared person the next time around.
In fact, all that frustrated anxiety is more likely to push me deeper into the habit energy that got me here in the first place.
Shittiest Possible Me will never be real, but I will definitely slide toward a pretty reasonable facsimile by sitting still and thinking myself ragged instead of making my best effort in this moment.
And I’ll slide even faster if I use my angry flailing as a defense against admitting mistakes I’ve made, separating them from who I am, and accepting reality on its own terms.
“I JUST. NEED. TO TRY. HARDER.”
It’s August 2014 and my pair and I are running like half a core challenge late. Everyone around us seems to have finished the first core an hour ago. We’re just now starting on the second one, which involves importing a huge collection of strings into a database, inflating them into ActiveRecord model objects, and running some methods on them in Sinatra controllers.
We repurpose a well-tested method we’d written a few weeks ago, and call it on a sample string to populate a collection called
@results within our
post route. We know how the method should work: the view needs to render the three results that we expect(!) to be there, assuming(!) everything’s running ok.
Undefined method `text' for nilClass.
We dart to the controller, tap fingers to keys, add a couple
puts statements to the top of the
post route, which is hard to spot at first, because we were hurrying the last couple of times we edited the controller file.
We hop back into the browser, go back a page, refresh the page, fill out the form, hit “Submit”. Check the terminal output.
@results is empty. Did we forget to even populate the database? We’d been running behind and feeling too much internal catch-up pressure to pay close attention to our process, so yeah, you bet your ass we forgot to populate the database. Figures.
This human embodiment of all my unspoken feelings of inadequacy disguised as a well-meaning cohort mate strolls by, says “yeah, might as well get coffee or whatever, it takes like 10 minutes to seed the db” and so that’s what we do.
We get back, the terminal screen is full of rake task spaghetti that neither of us stop to read because some people in the kitchen had been strategizing their way around the challenge two after the one we’re stuck on. There’s no time to read. I mash CMD+K until the words go away. The blank screen helps me clear my head a little.
Looking back, reading the terminal output in horror would have been the smart move right here.
The database is seeded, but the method call still isn’t populating the collection. Every time we try something new in the view or controller and agonize through another back-refresh-reenter-pray-submit cycle – the feedback loop is so fucking slow – nothing changes.
Somewhere in all this, lunch happens.
I eat too much. Emotions are goddamn delicious.
And now, after changing every instance variable and route name in our app, switching the method attribute back and forth in our form tag, and reading our migration fields out loud, character by character, we have come to this: reexamining a method that works, trying to convince ourselves we’d written it wrong.
We refactor it over and over, and each thing we try works on our test strings but not in the app itself. We are stumped and exhausted and a little pissed off. Most pairs are two challenges ahead of us by now.
It finally occurs to us, two grown adult humans who each paid a small boatload (a kayakload?) of money to be here and learn from people who had done this stuff before, to ask for help from someone who had done this stuff before.
The instructor is patient and kind. He speaks softly and slowly. Cons: My belly is too full and I am burnt out and now I kinda feel like I need a nap. Pros: It is impossible for my thoughts to race as fast as they’ve been racing when the person I’m speaking to refuses to be in a rush about anything.
Another pro: he’s encouraging as hell. As we talk through our understanding of how the pieces of this CRUD app are communicating with one another – an understanding that we’d spent the last 2.5 hours solidifying with our repeated renaming and rewriting – he is constantly affirming our shaky knowledge with earnest positivity. He shows us that we already know how the thing should work in a general sense, and then turns the focus to a detail that he’s probably been considering since we called him over.
“So, have you two checked how your method runs in the console yet?”
We had, and it hadn’t worked when we applied it directly to our ActiveRecord objects. And instead of figuring out why, we had back to adding Sinatra’s abstraction layers to our problem space. It’s a lot of extra noise to debug through. But we – okay, back that up, I’ll only speak for myself here – I already had so much other noise in my head at that point, so many expectations, so much shitty self-talk, that I never thought to dig deeper at the console level.
Ok, so now we’re back in the console. We run the method on our sample string, no results. We search the database for the first word that should have come back. No results.
We run a query to return the last 20 words in the database, come up with a new and nonsensical sample string that should bring one of them back, run our original, weeks-old, well-tested method, and holy shit there it is.
Then we try something so crazy it’s almost sane: we search the db for the first of the three words we’d started out looking for. Not as a method return, just finding by the attribute name that held the string.
And nothing comes back. The word hadn’t made it into the database. Neither had the other two.
Dimly, grimly, I become aware that we should have just read the fucking terminal output after we got our coffee. Or we could have used
create! instead of
create. Or we could have hopped into the console to search for words as soon as the seed file had finished running.
But we hadn’t, because we were feeling rushed and insecure. And people who feel rushed and insecure make silly decisions.
Re-seeding the database takes 10 minutes. Three minutes after that, we have a fully functioning app.
Usually, pairs at DBC high five at this point. We don’t. There’s nothing that feels celebration-worthy about this. Because celebrating means reflecting on what just happened.
Reflection desired? After wasting half a day on a stupid rookie mistake?
Oh, who gives a shit…
Bears. Beets. Back-breaking self doubt.
Here are a few things I’ve learned about myself.
I don’t do my best singing while I’m planning how I’ll spend the tips after my set.
I don’t do my best blogging while I’m daydreaming about how big the traffic spike will be on tomorrow’s stats page.
I don’t do my best parenting while I’m worrying about what my daughter’s adulthood will be like.
I don’t do my best debugging when I’m thinking about my timebox for this commit.
I don’t do my best anything while I’m thinking about being done instead of focusing on what I’m doing.
Don’t count your touchdowns before they hatch.
I can only find the joy in my work if I’m present while I’m working. Once I start to obsess over the results I want, I lose focus on the process that can get those results, and my work suffers.
I learned how to be an adult from a culture that labels people – smart, dumb, emotional, cold, disobedient, flighty, funny, lazy, gifted, good, evil – and subtly reinforces those labels from early childhood until death. “She’s totally a type A.” “People never really change.” “I yam what I yam!”
We grow up with stories, and those stories all have heroes, and most of the time, the heroes are heroes because they’re special. Katniss has special aim. Mario has special glutes and quads. Ender has special tactical awareness. Pocahontas has special empathy. Rey has a special sensitivity to the Force. Superheroes have special everything.
Neo has special debugging skills. I don’t. No one I know does. The best debuggers I’ve met have some combination of a few things:
- a habit of reading error messages slowly and carefully
- a willingness to accept that the first two or ten Google searches might be fruitless
- enough mindfulness to stay calm, humble, and attentive in the face of stress, uncertainty, and deadlines
- snacks on hand
- the memories of hundreds of hours lost to silly mistakes, and the lessons learned
- gentleness with themselves
My go-tos are 2, 4, and 6. I’m working on 5, which seems like the only permanent one, but I haven’t yet put in enough hours to have wasted hundreds of them.
This one time, I was leading a breakout for Phase 1, and a student asked a question that no one asks in their first week unless they’ve had some prior programming experience. It was a clever, insightful question that anticipated the edgiest of edge cases.
The moment they asked the question, I could sense the collective tensing up of 80% of the cohort. I could almost hear them beating themselves up – “Jeez, if that person can ask a question on that level, does that mean I missed out on something in Phase 0? Should I have walked into this breakout as a better-prepared human being?”
So I answered the question, gave the student kudos for thinking on that level, and then I added this: “That one must have stung you a few times before, huh?”
As he laughed and nodded, I could almost hear the sighs of relief. “Oh, so this isn’t magic at all, then. If this work hurts today, maybe that’s just the discomfort that will lead me to mastery tomorrow.”
Pictured above (left to right): Me coding in 2016, me coding in 2014.
There’s so much content now. We spend tons of time consuming the finished products of hard work, and eventually we end up assuming that the finished products are the rule and not miraculous exceptions: the few poems that weren’t crumpled up and thrown into the bin, the few thinkpiece ideas that weren’t iced by the editor, the few apps that didn’t die before the index page was styled.
We celebrate others, and judge ourselves, based on how easily the most excellent outcomes seem to arrive. We rarely take the time to consider the processes that helped make those outcomes so excellent, hard work done behind closed doors, incrementally, often painfully.
But when we do take the time, it’s obvious that arrival is just the result of the last steps we take. Before we can arrive, we have to walk. And if we lose sight of the path by fixating on the finish line, we not only trip over our feet, but we refuse to look back at the things that tripped us up, and we end up making the same mistakes all over again.
When I left home to start DBC’s Phase 1, I left my wife and daughter behind, and I promised them I’d be done in nine weeks. I knew repeating phases was a thing, but I refused to plan for that eventuality because I thought it would give me an excuse to slow down.
I was in a hurry.
So while other boots seemed fully engaged with the material and one another, I was constantly looking ahead to the next assessment, wondering whether I was moving fast enough to crush it in one shot, obsessed with my impending arrival.
With that attitude, what ended up happening was that every error I encountered, every mistake I made, every hour I wasted spinning my wheels without asking for help, felt like a threat to my expected(!!!) nine-week timeline. I couldn’t learn at my best pace because I was never fully in the moment, always wasting brain cycles on comparing myself to the fastest students in the room, those human embodiments of my inadequacies disguised as well-meaning cohort mates.
Those humans, real people I could have spent more time connecting with, working with, and learning from, became projections of my own hurry worry and negative self-talk. I started to see them as avatars of my own Best Possible Me, fixed quantities of awesomeness that I felt I could never leap high enough to touch.
My inner critic is an asshole.
I couldn’t resist the pun. I’m so sorry.
Recovering addicts know that living beyond the present moment is an exercise in futility. Any fixation on a long-term goal becomes a trap.
Each day of sobriety you get under your belt adds pressure: what if you throw away three whole months with one bad decision? And each day you continue the journey toward your self-defined goal – your expectation – applies pressure from the other end: “I’m so, so, so close to putting a year together, and only a fucking failure would stumble with the finish line in sight.”
Also, there is no finish line for a recovering addict. There is no point on a timeline that represents the result an addict really wants – total freedom from the compulsion to relapse, forever and ever.
All you get is this moment, and the next moment always depends on how well you manage to take good care of the moment you’re in now.
But it’s really hard to be mindful in every moment, so by convention, recovery groups offer advice that pads the timeframe a bit: “Take it one day at a time.”
If you can forget about how far you’ve come and how far you would like to go, you have a better shot at listening to your body and mind today, and finding alternatives to relapse whenever a craving comes roaring back into your soul, uninvited and unannounced.
And if I see you tomorrow…well, that’s a tomorrow problem.
An addiction is a thing you can’t stop clinging to, even as your life falls apart. We tend to tie the term to drugs, but ideas can be just as dangerous.
So can priorities.
And if that’s the case, I believe American culture is both a masterful drug dealer and a tireless enabler.
Compulsory education gets us addicted to results and shortcuts; if I can figure out how to ace the test, by cramming or cheating or sucking up to the teacher, I’ll “succeed”, and if I never really learn anything in the process, who cares? I’m not here to learn – I’m here for a GPA and a piece of paper.
Rugged individualism gets us addicted to seeking self-worth through comparison and disconnection; if I can figure out how to live as a lone wolf, by separating myself from the sheeple and arriving(!) at good ideas first and fastest, I’ll be “unique”, and if I can only feel worthy by comparing myself to people I see as less worthy, who cares? I’m not here to make friends – I’m here to win.
The 24-hour news/social media/advertising cerberus gets us addicted to wanting things. If I can come to notice every imperfection in myself and the world around me, and the flaws keep me neck-deep in a feeling of not-enough, I’ll be “motivated”, and if all I can do with my restless energy is explode in the direction of the next consumable item placed in front of me, who cares? I’m not here for fulfillment – I’m here to chase my desires.
If I’m addicted to results, comparisons, and desiring things, how can I ever be ok with myself in this moment? Result addiction takes me out of the moment. Comparison addiction takes me out of myself. And desire addiction takes me out of being ok with where I am and what I have right now.
If I’m trying to quit smoking, my Best Possible Me seems like the imaginary version of myself who never picked up a pack in the first place. Or maybe he’s the version who goes cold turkey and swats down every craving for a decade straight, through sheer force of will. It’s an expectation, a dream, a figment. Best Possible Me will never exist.
But I’m finally starting to realize that I might be wrong about that.
Maybe Best Possible Me is a real person, but I’ve been looking for him in the wrong place. Maybe Best Possible Me is not something I can aim for, or compare myself to, or desire, because maybe he’s been here all along.
Maybe Best Possible Me is Real Life Me, but only when he’s actually living in real life. When he’s awake and attending to this moment, focused and flexible and willing to see things as they are, even if they violate some unspoken expectation.
Maybe Best Possible Me isn’t a person, but a pattern – a habit of staying mindful enough to discern the next thing I need to do.
Addicts say that all the time, too: “Do the next right thing.”
And then the next one. And then the next one. There are no sunk costs. There is no long term. The only way to honor the past is to take care of the present. The only way to make tomorrow awesome is to take good care of today. This, right here, right now, this is all we get.
Everything else is just so much dreaming, and your dreams are useless unless you wake up and do something about them.
“But I’m still asleep right now, Roto-Richard.”
Sometimes, when I’m coding, my next right thing is to read an error message.
Sometimes my next right thing is to make my best guess, change one thing, and see what happens.
Sometimes my next right thing is to read the docs.
Sometimes my next right thing is to ask for help.
Sometimes my next right thing is to take a break, like when I catch myself losing sight of what the next right thing is.
Sometimes my next right thing is to reflect on what I’ve just learned.
A lot of times, my next right thing is to figure out what my next right thing is.
Next right thing, don’t go berserk after handing down your life lessons.
I’m 18 months removed from that Phase 2 challenge, and I have never forgotten to use
create! in my seed file since. I’ve also developed a habit of proving concepts in the console before I try to get them online. And I’ve gotten way better at actually reading terminal outputs instead of simply glancing at them to see if they look similar to things I’ve seen before.
I still fall into the pattern of banging my head against a problem for way too long before admitting defeat and asking for help, but it doesn’t happen as often anymore, and I don’t bang my head quite as long as I used to.
That hurried, harried, awful debugging session was formative for me in a way I couldn’t have anticipated in the moment. I thought I had lost half a day to a stupid mistake. But I’ve probably saved myself from facing at least a dozen half days since.
That afternoon, I had no desire to reflect on what I’d learned – I’d have preferred not to remember the day at all – but I had been blogging regularly for the previous four months, nightly for the previous three weeks, and so evening reflection had become a habit by that point.
So I did: As it turns out, my pair and I actually stumbled into a pretty solid understanding of how instance vars and params are getting passed back and forth, and damned if we didn’t solidify the shit out of that understanding today. Not bad, on balance. I still kinda feel like a failure, but I guess I got some good work done.
And it helped a little.
But what helped a little more was waking up the next day to find…that I had woken up. The world hadn’t ended. I wasn’t cosmically branded as Shittiest Possible Duke until the end of time. It was a new day, and yesterday had died, and looking ahead, I wasn’t sure where I’d stack up compared to my cohort on the upcoming challenges, but I didn’t care as much anymore.
Because there was new stuff to work on that day, and I knew I needed to stay present and ask for help if I wanted to make the most of my work.
My next right thing was to dust myself off and start again fresh.
The next step? Refactor.
It’s March 2016, and I’m not running late, because I listened to my alarm this morning instead of trying to clutch my dissipating dreams, and then I took a shower before aimlessly browsing Twitter as my family slept. The next train is scheduled to arrive in 2 minutes.
I hustle into the station. I tap my card at the turnstile.
This is where I am, right now, and I’ve been here before.
I walk to the machine, tap card to reader, give it the time it needs. I can’t will the machine to change how it does its work.
Menu screen. Read every option carefully. Find the next right button.
Add pass this time.
I select my duration, read the output. Select debit, wait, card in, wait, card out. I let myself glance left. In the distance, I see headlights peeking over the horizon.
Maybe I’ll make this one, maybe not. That’s a future concern.
I decide to return to the present. I do better work here.
I take my sweet time with the PIN pad. It’s strange, how when you look up at the screen to check your inputs, the buttons don’t seem to stick at all.
Receipt desired? Nah. No need to waste paper.
Besides, machines don’t make mistakes nearly as often as their users do.
I amble through the turnstile, through the door, onto the platform. The doors open just as I reach the end of the first rain shelter, which is exactly where I need to be. Without breaking my stride, I pivot left, step into the second car of the train, snag a solo seat – when you get on at Rockwell before oh-shit-I’m-almost-late-o-clock, there’s always an open solo seat in the second car – and I take my phone out of my pocket.
Normally, this is where I find a lot of stuff on social media to be angry at (why isn’t the world the way I expect it to be?!), but today I’m reflecting. Thinking about why this morning went so much smoother than that last time.
Thinking about lots of things.
I close Twitter, open Music, press play on Young Mountain, return to the home screen, open Notes, and start thinking out loud.