Itachi and Kisame — Asagiri no Kikyō, Naruto (ナルト) #81

The best programmer I know…

MrManafon
Homullus
Published in
11 min readMar 20, 2024

--

In the Danish language there is a word forventningsafstemme, that roughly translates to “alignment of expectations” but with a uniquely Danish focus on it being a two-way street. In other words, to clarify what expectations you have of each other prior to undertaking a project together — behind the wall of text, this blogpost is about the importance of being honest to yourself and the team.

I’ve been on a ski trip with NoA Ignite Denmark and downloaded a bunch of podcasts and articles to read while resting between the runs or waiting for a plane. One of them caught my eye — “The Worst Programmer I Know” and it got me thinking for days…

A couple of years ago there was a Twitter thread titled “The best programmer I know” that made the rounds. It led to fiery discussions for days, weeks even. It quickly became one of those implicitly recognizable resources that developers share with each-other to prove a point — like “The Twelve Factor App”, xkcd 378 or something like Cook’s “How Complex Systems Fail” paper, or quotes from Joe Armstrong’s legendary PhD thesis. I’d often share it when trying to describe what we otherwise might call an “ideal team player”.

Both were written by Daniel Terhorst-North , who I’ve coincidentally heard speak a couple of times at GOTO Amsterdam back when going to physical conferences was still a thing. I’ve never realized until now that it is the same person.

(If you haven’t read the original yet, now is the time. I’ve attached it at the bottom or at the link above.)

Thinking back to the original piece from 2018, I think that reading it had changed me, as well as the way I perceive what qualities an ideal team player holds.

Back then, I would always try to clumsily verbalise what traits I paid attention to, through generalised words like “inertia”, “drive”, “agency”, “curiosity”, “communication”, “culture”, “10xers”, “full-stack” which are hard to communicate as they mean different things to different people. Then I’d try framing them in a more concrete manner — this would cover polyglots, both in terms of their programming experience, but also other work experience, for example services, sales, design. For example, I’d spend energy claiming how Full-Stack actually has nothing to do with the tech they use, but instead with their worldview and readiness to tackle unknown challenges or loosely defined tasks.

But, there is such beautiful simplicity in him laying out illustrative and colorful examples that many of us can relate to. As Dan himself says, it was actually obvious all along, but hard to verbalise before he pointed it out.

Who is the best programmer I know?

When we talk about qualities in a developer, we often try to assign a quantitative or practical value to them, so we talk about languages they know, education, or perhaps their awards or expertise in their craft. Because of this we often end up drawing certain columns and admitting that much like in a game, it is an overly idealistic expectation, to find a person that covers multiple or all verticals.

Fundamentally, I think what Dan North did different is shifting the focus from thinking about people as computers or checkboxes on an HR-approved sheet, to describing general human traits in real-life situations. In that framing, a person can have none, or some or even all of these qualities, one does not negate the other. He managed to describe a mindset, not a curriculum vitae.

After re-reading these in 2024, I feel more strongly than ever, that these are the qualities that make a strong coder, architect, tester, colleague, comrade, leader — and that this is, in fact, what I’ve always valued when hiring or forming teams, without verbalizing it properly, more than any 133tcode tests, 500IQ questions or even POC apps.

Nobody is perfect and exhibits these traits all of the time, least of all me, so composing a team is an act of balancing these so that the team as a whole exhibits those traits. A team needs to be curious and ready to jump into the unknown, to have a breadth of experience and interest, to be extremely user-centric, ready to fail and fail fast, love what they do and respect what others do, and above all else, communicate decision reasoning.

Lost Vikings, the ideal team comp spectrum, some would say.

Each member of the team should be somewhere on the spectrum that Dan proposed, together forming a whole. It is not their traditional seniority or skill that form the tapestry, instead it is the way they act, communicate and learn as a whole.

If you look for engineer’s innate drive to consider the wider effects that their work has on the users, project’s future and the immediate team, I can vouch from experience, that you can hire a person who doesn’t know your programming language, paradigm or industry, and find immense success, given a team that complements them well.

In fact, this is what I also look for in the employer. Remember, a job interview has two sides. It makes me endlessly proud that we’ve managed to nurture a culture of appreciating these traits at NoA Ignite Denmark and having a team built on that (Lencioni’s Ideal Team Player) foundation. Honestly, it made a huge impact to my joining NoA last year.

And it wasn’t the first time either. If I look back at my career choices, I can easily find traces of such a culture at most of my previous workplaces — bias through selection. (if I’m using that term correctly)

Who is the worst programmer I know?

Dan’s new article talks about the significance of having “playmakers” in the team, as opposed to focusing on pure measurable delivery.

The idea being that we shouldn’t hold individuals to generic delivery metrics, such as velocity points and hours, but teams instead. If we think back to what I wrote above, we build teams by combining people with differing traits, in order to form a well-rounded whole.

We should normalize the idea that looking at individual members of the team while assessing the delivery will never give us the whole picture, as different individuals in the team respond to different metrics of productivity.

In his example, a craft lead or a staff engineer won’t collect the same number of points on their own, since their duty is to enable the rest of the team, lead by example, unblock or teach. Thus, your overly generalized delivery/velocity metrics, won’t produce much on paper, but what you often don’t see is, that without this core supporting role, the overall velocity drops significantly. You may even be producing — but not investing.

Measuring individual performance must require deep understanding of context, and a much closer look at the role they play. By excluding a piece of the pie from our idyllic team that I mentioned above making it unbalanced and rudderless.

I remember struggling with this shift in 2018. I’ve coordinated teams before, but my first serious leadership position was supposed to be a merry progression, however, some 3–4 months in, I was deeply unhappy with my personal delivery and slowly burning out with trying to compensate. Damn it, this is what I was always measured on, and after all, I’m a lead because I’m supposed to be best at stuff! And now, I’m failing.

I was additionally over-focused on making comprehensive systems of measuring velocity points, making everyone anxious, and wasting energy and company time, because I’ve read somewhere that this is how its done.

My manager at the time recognized this struggle from his own experience, and he helped me overcome it. First through example, and later through open discussion, expectation setting and coaching. Eventually he saw a change in me, and in my team, and said — “Now you get it. The company is not paying you to code. Your job is to support and elevate your team with all you’ve got.”

Teams deliver — Ideal team players make it possible

From today’s perspective, I’d like to widen that even further, and loop it back. Every one of us affects the rest of the team, and while it may be MY primary responsibility to nurture the servant leadership culture, all other players on the team is what makes the overall balance possible.

If we look back at the previous section, it is natural that not all members will have all “ideal” traits, nor will they fit together “Ideally”. We are all different and imperfect. But the gaps can (and must) be filled through nurturing a culture of communication and over-communication. It is not about how we “pick” the team members, it is about how we cultivate a communication culture.

This takes us back to forventningsafstemning from the beginning. Whenever I’ve failed at my role of leading the team, it was due to not being on the same wavelength as my teammates.

I’ve thought about forventningsafstemning from the perspective of expectations of delivery or behaviour — but looking back at my failures, I’ve been lucky to work with some amazingly skilled people, and it is always about communication, and never about the tech or lack of skills.

Forventningsafstemning should be about our expectations of the human traits, the way we communicate, share, learn and teach, about the way we talk to stakeholders, designers, customers, and most importantly about normalizing talking about our individual deficiencies.

This should be present in your team’s everyday life. It can be as simple as making sure teammates aren’t shy or afraid to ask tech questions in Slack or to diverge from a “well-known” approach.

Try to weave this approach whenever you can. Start meeting by laying out the expectations, ask others about their expectations. Enjoy that little silence, which allows others to speak, listen more than you talk (I’m not particularly good at that one yet), ask for advice and opinion regardless of seniority. Ask your colleagues about their interests. Make sure to encourage them to learn unrelated skills. Get to know the reasoning behind their opinions.

Make it inclusive, lift up your juniors, soften your seniors. Talk about failures and course corrections. Make it clear that the best opinions are clear and strong, but loosely held.

Talk openly about what you wish to see. Over-communicate intent, over-communicate reason and expectations. Be ready to change your expectations, it’s a two way street.

This reminds me of an “ideal” team idea in Star Trek. In a healthy team, an estimate or problem-solving won’t be undertaken by the leader, instead the expectation should be that all members are experts on their respective domains and we should trust their judgment. I believe it was Jean-Luc Picard that had a line about never allowing his team to feel left out, not heard, not considered, even when he is making a completely opposite decision. Sounds silly, but that line stuck with me.

A leader can (and must) set this narrative through example, but the foundational expectation is to make sure that it is the whole team’s task to make it actually happen. This takes us back to Dan’s Twitter thread, as this is exactly what he is describing. Damn thats a good thread…

The Twitter thread that started it all

For those of you who still have your X accounts, the original can be found here.

Due to the transient nature of the internet, things disappear. The original thread is now hard to find, locked behind an X signup form, and Dan North is not even on Twitter anymore. There are re-posts, here and there, so I’ll leave a snapshot of his original thread below, hoping it helps someone.

Sharing wisdom and keeping it accessible is important, this is a great opportunity to share with a wider audience. Original transcript below:

[He happens to be male. This is incidental. I know plenty of female programmers with many of these characteristics.]

  1. He sees what is really there. I see what I am conditioned to see. Once he points it out, it was obvious all along.
  2. He solves the problem at hand, not a fancy generalised version of it.
  3. He writes simple, obvious code that is easy to change later.
  4. He knows he doesn’t know, but tries anyway. He then iterates on his attempts until he gets there. This requires humility and perseverance.
  5. He chooses the right tool for the job, even if he hasn’t used the tool before. He figures the investment in learning the tool is worth it to solve the problem the right way. This means he builds simple solutions rather than easy ones.
  6. He knows when to hack and when to invest in quality and makes these choices deliberately. His hacks are still written in a way that they are easy to stabilise later. He builds small, intention-revealing components that can be easily refactored, restructured or replaced.
  7. He is generous with his knowledge and takes genuine delight in seeing people learn. He taught me that the learner should always drive in a pair. You feel like you’re going slower but you both get better faster. Note: the learner isn’t always the less experienced person.
  8. He doesn’t constrain himself to software. He looks at the whole situation and will happily refactor a process, make physical hardware, build a supporting app, challenge the premise of the problem, whatever it takes. It just happens to usually involve software.
  9. He stays informed by plugging into various networks, both public and private, of individuals and groups that challenge and advise each other.
  10. He is a net contributor to any group he is a member of. Not just through information, but through encouragement and support.
  11. He has the ability to Just Start. I will procrastinate, read the tutorials, gen up, etc. He just goes from stop light to stop light until he is done.
  12. He works really bloody hard at this. There is no “innate programming gift”. The way to make something look easy is to do it again and again and again, and be prepared to be rubbish at new things until you get better at them. This is hard, especially IME if you have a big ego.
  13. He doesn’t follow any single method or methodology, but he learns about them in case they may be useful, and so he has context when other people talk about them.
  14. Related: He learns languages, tools, libraries, programming styles. This gives him different perspectives.
  15. He has interests outside of programming, including physical activities like acrobatics, and takes his family life seriously. This sets a good example to less experienced programmers that they should keep a decent balance.
  16. He sends people home at the end of the day.
  17. He has amazing attention to detail, but doesn’t take himself too seriously.
  18. He is as comfortable designing (awesome) web pages as he is designing (awesome) backend infrastructure and (awesome) distributed architectures. He got good at them by studying them.
  19. He watches how people use his software, figures out what frustrates them, simplifies it, and eliminates their frustration. He doesn’t make assumptions about what people want from his software, he asks them and he listens.
  20. He studies the business domain he is working in, and its inhabitants, so he can express domain concepts clearly in code and connect them together to solve meaningful problems.

--

--