The following is a document supporting my talk: "You're Not Special"
I assert the following: "There is no such thing as natural talent."
A provocative statement, but not specific enough to be proved or disproved. Allow me to be slightly more specific and state my understanding of what the current evidence has shown us.
Given the process of learning a complex skill well enough to become a world class expert
- Differences in our starting points look like rounding errors.
- When we are able to factor out the variations in the quality of practice, which is rare, our rate of learning seems to be roughly equivalent.
I am basing this assertion on the following literature:
- The role of practice in the development of performing musicians
- The role of deliberate practice in the acquisition of expert performance
- Skill in chess
I would be delighted to be shown that I either interpreted these papers incorrectly or that they've since been debunked.
My speculation, not evidence based:
I suspect that there are fields where "almost identical" and "rounding errors" make a big enough difference to count. I suspect competition based fields like elite athletics fall into this category.
There are times when our body is present but our brain is not. Writing code when we're not fully engaged can be challenging but it's possible. I might be checked out if I have an especially bad insomnia streak; it becomes much more difficult to concentrate.when I hit my 3rd or 4th day in a row without sleeping much. The following Bulleted List Of Unsolicited Advice™ contains the insomnia coping strategies that have worked for me.
- Turn off the obvious distractions. I'm looking at you, Twitter.
- Keep the blood sugar level. Being tired sucks, but being tired and hungry is lethal.
- Be honest with anybody who's depending on you. Let them know that you're not operating at peak performance and let them know why if you can.
- Pair. Pair on problems, pair on planning, and pair program. Don't swim alone, kids. See the above point and let your partner know what state you're in and that you'll be leaning on them.
- Zoom Out. The worse off my brain is, the worse I am at making good tactical decisions. When I'm tired, I assume that my code micromanagement abilities are wrong and that my partner is always right. On the flip side, I seem to be better at keeping big picture focus when I stop trying to drive the code directly. In short, if your partner needs to drive the code then you may need to be project manager for a day.
- Go home. If nothing is literally on fire and your brain just isn't functioning then just go home and get some rest if you can.
I've been lucky enough not to suffer from sleep issues in the past few weeks. Here's hoping that neither you nor I need this list anytime soon.
This isn't a post that I want to write. It's a story about me and it's limited by my memory of a night. I've been making excuses for not writing this for months now and it's time to stop procrastinating.
The purpose of this post isn't anger and it's not closure. I'm posting it because right now our only recording of it is now a deleted tweet. It's all too easy to close our eyes and wish it didn't happen. I know, because that's how I've been spending the last few months. It's so much easier for me, as a able-bodied hetero white dude with a beard, to pretend that this doesn't happen and tune out. The purpose of the post is to make this harder to ignore.
Because this shit happened.
Trigger warnings for assault, I think I'm supposed to say.
January at a resort bar for a conference. I had been a member of the Columbus Ruby community for a few months and a professional developer for slightly less time. It was the first night of my first tech conference and I was standing there talking with another developer from Columbus.
It was slightly before midnight at the resort bar while the other developer and I were talking with a rotating set of people in one end of the space. Being new I knew almost nobody there; it was later and most of the crowd had already headed home.
Looking over, the other developer pointed out a thing. It could end up being an embarrassing story or the last image before a train wreck. I knew of the man, head of operations for North America of a company that ran the largest Ruby shop in Columbus. The woman was at least 15 years younger, at least 100 pounds lighter, and at least 2 tiers lower than him on the corporate hierarchy at the same company.
We went back to whatever conversation, naively not even considering the possibility of a train wreck. What I remember as 5 minutes later the other developer looked over and said something like "oh shit." I looked over and saw a train wreck, now in progress. The executive's posture and actions aggressive; "no" was not a possibility. She was visibly upset and shut down. That's an understatement. I saw somebody trapped in a nightmare, in public. That freeze frame is burned into my brain.
The other developer was also at least 2 tiers lower than the executive in the same corporate structure. I think we both expected the universe to right itself. A few seconds later, when it became apparent that this was not going to stop on its own, the other developer put a stop to it.
I don't know what would have happened if that other dev, now a dear friend, hadn't been there to step in. How much longer would her nightmare have continued? Would I have noticed? Would I have let myself notice? Would I have walked over and asked if everything was OK?
I don't know the answers to those questions and I hate myself for that. Never again, though. I will never be the bystander who "didn't want to get involved." The pre-trainwreck body language that I could lie to myself about before is now crystal clear. That sense that something's wrong. I will walk over and say something self deprecating to give whatever future woman a chance to disentangle herself. No matter how powerful he might be in a very small community, no matter how little I know about the people or the situation.
I'll have to because I cannot live with feeling this way again.
This is the reference guide. The manual that should sit by your desk at all times just in case you need it. I'm sitting here typing right now and fighting down an anxiety attack because my copy is packed away in preparation for our move and NOT by my desk. It's comprised of 68 small tips that will make your code delightful to behold.
- Prototypal Inheritance
- IIFE's and closures
- Style Guide
Be mindful of the code's style. This one isn't the single source of truth, but it's as good as any to get started with.
No matter what anybody tells you, do not use a library like require.js as a beginner. If you're advanced enough to understand the tradeoffs, then by all means.
Update: I'm adding more episodes to the end as people suggest them.
The Ruby Rogues Podcast is awesome, but not all episodes can be equally awesome. These are the ones that have really stuck with me so they're the ones I recommend to friends.
For the rubyists:
- OO Design with Sandi Metz
- Robust Ruby with Ara T Howard
- Therapeutic Refactoring with Katrina Owen
- Objects On Rails with Avdi Grimm
For the programmers:
For the humans:
The Pragmatic Programmer recommends learning a new language each year as a way to prevent our skills from atrophying. I couldn't agree more, and I know exactly which language you should learn next.
Whatever the heck it is that you're writing every day.
Learn that one because I suspect it might just come in handy. Study the little nuances of the workhorse data structures so you never need to read their docs. Be able to split a string, round a number, and forward a method. All from memory.
Learn your server side framework of choice as an extension of this. Display text on a webpage, text that came from the database, text that was put into a database via a form submit. From memory, with minimal code generation. Maybe slide your Haskel book aside for an hour and work on this instead.
Oh, and if you must learn a new language right away I have a suggestion for that too.
I often get asked where to eat lunch or where to take guests who are visiting Columbus. This is what I came up with off the top of my head given a 1 hour constraint.
If you have the time then go on a food tour with Columbus Food Adventures. The tours are a collection of the best places serving the food they are the most proud of. When you're getting your hand held by obsessive foodies then you are getting the best dining experience in Columbus,
Skillet is my favorite Columbus restaurant. Locally sourced simple fare cooked with skill. The local sourcing isn't just a badge to put on a menu; they find food that's either not available to the bulk restaurant suppliers or of such high quality that it's not worth comparing. Today I had duck egg carbonara where the egg's yolk was so yellow that sunglasses were required. They're known for weekend brunch but their lunches and dinners during the week seem to be a well kept secret.
Bono Pizza is still the best pizza place in Columbus. They cook pizza in a wood fired oven that's hot enough to leave a slight char on the top of the crust while the rest is cooked to perfection. No A/C and occasional long lines so don't be afraid to order ahead.
Kitchen Little is where I see more restaurant owners eat than anywhere else I go.
If you allow a guest to leave Columbus without experiencing Jeni's Ice Cream then you are a bad person.
I don't make it to Basi Italia here as often as I would like but they're brilliant every time I do.
Explorer's Club has gone from great but inconsistent to nailing it every time I walk in the door. I would average 3 lunches and 2 brunches a month here and they were great every time.
For the Scotch fans, visit Wings in Bexley.
But you don't have to take my word for it.
We need both of them, you know. Grit gets the attention; it's sited as one of the most common attributes of wildly successful individuals. Far beyond intelligence, the willingness to stick with a task long past the point of boredom or doubt. The ability to stay focused despite the nay-sayers telling them that it cannot be done. The capacity to string hours and hours together for a self appointed apprenticeship with no pay knowing that success would be mere years away.
What gets less attention is the hustle. That sense of urgency that's only ever felt by somebody fighting a clock. This isn't panicked rushing which only leads to frustration, but obsessive streamlining. The willingness to avoid escapist activities like TV knowing that those hours each week takes away from a pursuit of mastery. The ability to practice right now instead of waiting for the perfect time with just the right wind speed and pollen count.
I recently was faced with the fact that I'm pretty good at the grit and generally awful at the hustle. I'll stick with a task long-term, but I'll find other activities that must be done first or can never quite find the right time to practice consistently.
My new philosophy is that the time to work on getting better at development is right now. When I figure out what my stupid bug was on a side project 10:00PM after spending 2 hours stuck on it, that leaves another 2 hours of possible work before sleep. 20 minutes of downtime while dinner marinates? Review some submissions on exercism.io. 5 minutes in line at the pharmacy? Review my index cards of stuff I had to look up yesterday.
TIme for me to stop crawling the path and walk it instead.
I find that teaching others is a highly effective way to get better. However, this only works when I'm putting full effort into the task and using feedback to optimize.
If I give instructions to a novice, I should probably use simplified rules and half truths at first. Giving the nuanced rules to that novice may frustrate them. May put enough of a roadblock in their path to stifle growth. I need to watch the student to see if the answer was complete enough to be useful but not so detailed as to confuse them. Based on that feedback with this student, hopefully I'll limit the damage that I deal to the next one.
However, if I only understand the simple heuristic then I will never advance. To give a simple but effective answer for a complicated question, the teacher MUST understand the nuance. Must assume that they got it wrong and verify those nuanced points with an authority.
Dairy cattle, specifically. And that's a very good thing for developers.
Any drive through rural United States will display a variety of agriculture relics. Skeletons such as a rotting barn, some rusting field equipment, or a lone silo standing sentinel over the ghost of a long abandoned farm. These are monuments to the passing of time, to an age before industry allowed the consolidation of dozens of family farms into large corporations. The family farm has been rendered almost extinct by such efficiencies with a single notable exception. The dairy farm.
The dairy cow doesn't really scale well. Their ability to produce milk will be greatly reduced by the stress caused by over-crowding and other forms of mistreatment. Milk production relies on an active reproduction system in the animal and is crippled by those stressors in all the ways that meat production isn't. If you attempted to treat your average Holstein the same way Perdue treats its chickens then you're going to get a cow that gives half the milk and lives a quarter as long. See, that cow longevity is of great importance; short of a time machine it takes 2 full years to make a new lactating cow. If you don't treat your cows at least as well as you treat the family pet then that investment is squandered.
Large dairy farms can and do exist but so do the very small ones. The very large ones have figured out how to treat their animals decently and the small ones survive by staying lean. The same does not hold true for corn, pork, beef, soybeans, or just about any other type of commodity farmer that I can think of. Those farms may be family owned, but they probably a corporation in their own right with a fleet of equipment and many employees. There are delightful exceptions amongst farmers that find their own market and exploit that niche, but that doesn't further my point so lets ignore them.
Right, developers. And a point.
One of my favorite books that I've never read, The Passionate Programmer, is truly excellent and I cannot recommend it highly enough. It's easy to forget though that it's the second edition of My Job Went To India And All I Got Was This Lousy Book. Somewhere between 2005 and 2009 we developers seemed to have lost this anxiety over every last development job being moved overseas. Do you remember how everything was going to be outsourced and all the code was going to be written in India? That never happened. Well, it might have happened to the Purdues of IT like IBM, but it never happened to the rest of our industry. It turns out that the types of conditions that almost work for call centers and industrial chicken farming make for just awful software.
See, writing effective code is a frigging strange process that is like no other human endeavor. I've heard comparisons to engineering and science and art and a trade. And I say they're all way off the mark. They're just as accurate as comparing the model of an atom to the solar system or comparing a developer to a 1,500 pound lactating bovine. The real answer is that development is none of the above; it requires the empathy of a social worker, the precision of an architect, and the creative flair of a different architect who has creative flairs. Or an artist. They have creative flairs too. Its hard, harder to do well. Developers are actually creatives. Our process isn't turning a crank or pressing a button but requires leaps of intuition and lateral thought. That process breaks down if the developers are under stress or if they are not in a position to empathize with the product owners. It breaks down if we're over-crowded; large teams are notoriously inefficient compared to the small ones.
Developers, like dairy cattle, don't scale.
We don't scale in this fundamental way that may be the first time seen in human history. And because of the difficulty of the vocation and the rarified conditions required to produce good software, there is a major shortage of us. The demand is outpacing the supply to such degrees that the biggest complaint I hear amongst our peers is all the recruiter spam. You know, how to deal with all those people offering to pay us money.
Never before have we had this much power over where we work and how. Employers are in abject terror over one or two people leaving at the wrong time and touching off a brain drain. No longer are we crammed into cube farms and buying books about flat worlds featuring outsourcing. 6 digit salaried positions stay open for months because applying for the job involves uploading a Word document and wearing khakis. We developers have serious power and it's not going to go away in our lifetime.
Unlike the dairy cow we have the choice to do something with our relative privilege. How then shall we expend it? Shall we amass more power? Or maybe we could show the chickens tryruby.org.
When faced with this error when pushing a Rails 4 app to Heroku:
-----> Writing config/database.yml to read from DATABASE_URL
-----> Preparing app for Rails asset pipeline
Running: rake assets:precompile
could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 5432?
$ heroku labs:enable user-env-compile
The gist is that the Heroku env variables are not set when your app begins to precompile the assets. Rails 4 is supposed to not load the full app during asset compilation, but sometimes it does anyway. Since those Heroku environment variables aren't set yet, like the location of the database or the Redis server, the app fails. That heroku labs command above makes the environment variables available early enough to prevent this specific brand of failure.
Here is an alternative solution.
I aspire to being wrong.
I prefer to state my wrong uttering as questions or suggestions. These types of wrongnesses (I hope) cause people to think. They drive the team to write better software because they needed to consider my flavor of wrong before shooting it down. Maybe my incorrect statements interact and co-mingle with their almost-correct ideas and produce better ones. Maybe they even adopt my wrong ideas wholesale and we're all surprised together at me being slightly less wrong than expected.
This isn't irony or reverse psychology but my best ideas held with the conviction that I'm wrong. But I must consistently share my wrong ideas freely and without shame. Keeping the ideas to myself will ensure that I walk meekly into a life of mediocrity.
Sometimes I still slip up and assert loudly that I am right and my rightness should be listened to and that, by extension, others are wrong. This is awful for me and everybody else because it means that either
- I'm right and I'm an asshole, or
- I'm full of crap and I'm an asshole.
In both cases I'm not learning anything and the project becomes worst because other people feel bulldozed and disengaged. They'll shut down a very little bit as they loose a little bit of autonomy and become every so slightly less invested, if not entirely disconnected.
But approaching a technical discussion from the stance that I'm wrong empowers other people. It increases others' investment in the success of the project as they watch their own ideas take flight instead of just being tasked to implement my own.
What if the other idea is truly disastrous and my own is the only one that can save us from ruination? This is a hallucination of mine that reoccurs every once-in-a-while. I must simply remind myself that everybody else working on the project is as smart as me and as invested in success just as much as myself. If that isn't the case then me throwing my weight around and being right very loudly is going to make the situation for-reals worst.
If the project environment is safe for short term failure with non-judgmental, quick feedback then I will have an opportunity to reintroduce my own wrong idea later where it can be re-evaluated and perhaps adopted after all. By taking the stance that I'm wrong and defaulting to the other decision, either
- I was actually wrong and I learn something, or
- I was actually right and somebody else learns something
So please accept my apologies as I'm still right every once-in-a-while. I'm only human.
Challenge: remove the second line from a given file across all local git branches. Bonus points for spending longer trying to figure out how to do it with a single command than just making 18 changes.
git filter-branch --tree-filter 'touch game_test.rb && sed -i.bak 2d game_test.rb && rm game_test.rb.bak'
- We can run a command against every branch of a repo with
git filter-branch --tree-filter command
- Typically we see a find and replace pattern with sed such as
sed s/find-me/replace-me/g file >> another-file
- Much to my delight we can just remove lines wholesale with the d flag.
- sed 2d file outputs the contents of file to standard out with the 2nd line deleted.
sed 2d file >> another-file
- Sed's -i flag allows us to operate on a file in place
sed -i pattern file
- We need to create a backup file for OSX otherwise we get an error:
sed -i.bak pattern file
- Putting that together, we can delete the second line of a file without opening it with
sed -i.bak 2d file
- The && operator allows us to run two commands on the same line:
command && command
- Since OSX forces us to create an unwanted backup file when we use the -i flag with sed, we'll need to remove it right after running sed. Let's do it in the same line:
sed -i.bak 2d file && rm file.bak
- Not all of the branches have our target file which will make sed fail. Let's create the file first as a hack.
touch file && sed -i.bak 2d file && rm file.bak
- Now lets run a destructive command against every local branch!
git filter-branch --tree-filter 'sed -i.bak 2d file && rm file.bak'
On August 22, 2012 I became a professional programmer. I spent the 7 years before that as a Direct Mail Analyst doing repetitive, familiar, nonthreatening work in Lancaster, OH. I lost those 7 years in the blink of an eye.
The last 10 months, though. The last 10 joyous months feel like they've lasted 10 years.
I started thinking about that perception of time when introduced to the Time Hack Project. Matt Danzico spent a year trying new experiences to fool his brain into thinking that he was living longer. The reasoning is that we perceive time moving more slowly when trying something new and experience time moving more quickly when engaged in familiar tasks.
Interesting, but I think that we can take a look at this from a different angle. What if we use that perception of time as an alarm? "In Case of Lost Time Break Glass" When May goes by in the blink of an eye, that's a warning flag. When a year disappears on us, that's a klaxon. That's our brain shutting the hell down because we're not throwing anything challenging its way. There is no need for us to pay attention when there are only safe, boring tasks for it to work on.
Please stop the shame bullshit.
I have an especially low level of tolerance for loud developers that cause quieter developers to feel bad for not writing code in a specific way. Making people feel crappy doesn't improve their code, it just makes them feel crappy while they write ineffective code.
Shame corrodes the very part of us that believes we are capable of change.
That quote is from this piece on a public shaming ad campaign in NYC. Never mind the crushing, dehumanizing aspects of using shame to change the behavior of others as there is another aspect that's far more damning.
It doesn't work.
It seems to me that as programmers we should be reviewing data on the efficacy of our technique and adapting appropriately. This applies to unit tests or using shaming language to convince others to unit test in a presentation, a book, or at work. The data is in on both of them. Unit tests work when written first and shaming others does not.
One bite at a time? What? How are you even a project manager?
If we have to eat an elephant, then we start by renting some commercial freezer space, a chainsaw, and a vacuum sealer because we're not getting through this thing in a single sitting. How did we even come into the possession of a dead elephant that needs to be disposed of? How long do we have to make this thing disappear?
What? Whoah whoah whoah whoah. Whoah. So we've got a hard deadline of 4 days and don't yet have an elephant of any sort, much less a freshly butchered one? No, I don't think "spike out a trip to Africa and look for a sick one" is a reasonable first step. Yeah, no, we cant just "use a jQuery plugin for that."
How about we take the product owner out for some drinks and manage expectations? We can find out what they're trying to accomplish with all the endangered animal murder and see what else we can do for them.
*The correct answer is "by cheating."
That is the constant refrain from our brain, so please allow me to present a rebuttal.
What you have to say
- Isn't irrelevant.
- Isn't so basic that everybody knows it.
- Isn't wrong.
Asking your pair "what the hell are we even doing" will save their life. A few hours of it, anyway.
An afternoon spent in isolation, banging out code, is an afternoon wasted if we're not even solving a problem that somebody cares about. Avdi Grimm relates a story where he is building a screen scraper to access content, an arduous process, and it did not occur to him to just parse the RSS feed that he helped define. A pair sitting with him would have pointed that out very quickly. I have done far stupider things in isolation for far longer that a pair would have prevented.
Sometimes we need to get stuff done while alone, though. Being pretty horrible and blaming not having a pair is one option. Another option is the judicious use of pomodoro's. In brief, a pomodoro is a 25 minute distraction-free work period followed by at least a 5 minute break.
This pattern of 25 minutes of concentration followed by a hard stop prevents the insidious flow from happening and allows or brains to reset. We have a chance to stop fixating on hard problems that need not be solved and focus on the ones that other humans care about.
I try not to code alone but when I do it's never for more 25 minutes at a time.
Every trip out to Google for something we do not know costs 10 minutes. If our search returns visited links then that was 10 minutes needlessly wasted.
It's important that I write what I didn't know with pen and paper because I type for a living. There is something about seeing that information in a second context that etches it into my brain. So much so that the mere act of writing the syntax down immediately before using it is often enough to induce memorization without the need to review the information later. Waiting until I need that information a second time (looking for the purple links) before committing it to paper provides a great filter so that I'm not committing obscure 1-time-use trivia to memory.
I now produce at double the speed that I used to because I'm not constantly shifting focus between my work and a browser. I also find that I'm more creative. Since I now speak fluent Ruby I can use lateral thinking to compose thoughts outside of a phrasebook. The speed is wonderful but that increased creativity means that I'm more likely to build stuff that somebody might actually use.
That seems like a pretty nifty metric, right? Building a thing that is used by humans.