DEV Community

Cover image for Software Engineering is a Loser’s Game
Tyler Hawkins
Tyler Hawkins

Posted on • Updated on • Originally published at levelup.gitconnected.com

Software Engineering is a Loser’s Game

I’ve recently become fascinated by the idea of “winner’s games” and “loser’s games.” There are several great articles which explain the idea in depth, but here’s a quick summary:

An observation was made by Simon Ramo in 1973 that there is a big difference in how games are won in amateur tennis versus professional tennis.

When two amateur opponents are playing, the game is often won not through the winner’s great skill but because of the loser’s mistakes. The loser often commits unforced errors by hitting the ball out of bounds, missing easy shots, or double faulting. In other words, the loser beats himself. Points are “lost” by the loser more than they are “won” by the winner. This is a “loser’s game.”

When two professional opponents are playing, the game is won primarily due to the winner’s skill. Neither player commits many unforced errors. The winner places his shots well and outperforms his opponent to defeat him. Points in this kind of game are “won” by the winner more than they are “lost” by the loser. This is a “winner’s game.”

So, if you’re playing a loser’s game, a winning strategy is to simply try to avoid making mistakes and let your opponent beat himself.

(If you’ve ever played tennis or ping pong before, I hope at this point you’re nodding your head in recognition. As an avid ping pong player, I’ve seen this scenario play out in the office at work on a daily basis.)

The application of this observation is that you should attempt to understand whether any given activity you’re involved in is a winner’s game or a loser’s game. Gaining that understanding teaches you how you should play the game.

You can read more about these ideas in this article by Charles Ellis, this article from the FS blog, or this article from Ben Hosking.


Parallels to Software Engineering

Now, what if we consider software engineering to be a loser’s game? That is to say, we often beat ourselves by committing unforced errors and making mistakes. If we are amateurs, so to speak, how can we keep the ball in play rather than hitting it into the net?

It’s a simple thing to say, “If you want to be good, just stop making mistakes.” But that’s somewhat unhelpful. That’s like saying to those in poverty, “Why don’t you just stop being poor?”

It’s also unhelpful if we take this analogy too far. If avoiding mistakes is the ultimate goal of software engineering, is the best software engineer the one who writes no code or does nothing? Obviously, no. Software engineers are paid to write code to help bring to life some product in order to achieve some vision (make the business money, solve a real-world problem, simplify a task, etc.), so that must be the real ultimate goal.

So it appears that we must balance producing valuable output with avoiding mistakes. This leads to an interesting thought experiment: In what ways do we beat ourselves, and how can we avoid making these amateur mistakes?


Unforced Errors

Here’s a list of possible unforced errors we commit. I’m sure you may be able to add more to this list as well.

  • Not understanding the problem before trying to code a solution

  • Not understanding the tools or programming languages we use

  • Not carefully reviewing our own code before asking for a code review

  • Not manually testing our own code before asking for a code review

  • Not writing unit tests

  • Not following agreed-upon company standards


Solving These Unforced Errors

Now that we’ve identified some potential unforced errors, how do we avoid making them?

For starters, we can put safeguards in place to help us catch and correct our mistakes before they become too costly. All code repos should be configured with code linters, code formatters, and a suite of automated tests. These safeguards can be run as part of a CI pipeline prior to allowing any code to be merged.

We can also be more thorough in our own attention to detail when writing code. After creating a merge request, we should always do a self code review before asking others to review our code. We should always manually validate our changes as well.

Nothing is more frustrating as a code reviewer than reviewing someone else’s code who clearly didn’t do these checks themselves. It wastes the code reviewer’s time when he has to catch simple mistakes like commented out code, bad formatting, failing unit tests, or broken functionality in the code. All of these mistakes can easily be caught by the code author or by a CI pipeline.

When merge requests are frequently full of errors, it turns the code review process into a gatekeeping process in which a handful of more senior engineers serve as the gatekeepers. This is an unfavorable scenario that creates bottlenecks and slows down the team’s velocity. It also detracts from the higher purpose of code reviews, which is knowledge sharing.

We can use checklists and merge request templates to serve as reminders to ourselves of things to double check. Have you reviewed your own code? Have you written unit tests? Have you updated any documentation as needed? For frontend code, have you validated your changes in each browser your company supports? Have you ensured that all user-facing text is translated? Have you ensured that the UI meets accessibility standards and guidelines?

By performing these checks ourselves, aided by automated tools, we show an added measure of professionalism and respect for our coworkers. Trust will grow and velocity will increase. The key is to be diligent and disciplined.


Conclusion

Software engineering is a loser’s game. So let’s learn to play the game and stop losing to ourselves.

Oldest comments (57)

Collapse
 
sangpham2710 profile image
sangpham2710

high-quality content

Collapse
 
thawkin3 profile image
Tyler Hawkins

Thank you!

Collapse
 
pedrobritto profile image
Pedro Britto

Thank you for this post, Tyler . Thinking of software engineering as a loser's gamer is really insightful and you made some good points there. By not using automation and not following some simple checklists we are in greater risk of beating ourselves down. It's quite easy to avoid.

Cheers!

Collapse
 
thawkin3 profile image
Tyler Hawkins

Thank you Pedro!

Collapse
 
gokulaet profile image
Gokul Raj

Thoughtful content and Well Written...!!! Thanks

Collapse
 
thawkin3 profile image
Tyler Hawkins

Thank you Gokul!

Collapse
 
apongpoh profile image
Apongpoh

Thanks for the awareness! well written article.

Collapse
 
thawkin3 profile image
Tyler Hawkins

Thank you Apongpoh!

Collapse
 
bdelespierre profile image
Benjamin Delespierre • Edited

I like your article, Tyler. And I love your metaphor, I believe there's some truth to it. But I I've always professed quite the opposite:

An expert is a person who has made all the mistakes that can be made in a very narrow field.
― Niels Bohr

My advice, especially to new developers, is this:

Get out there. Code something. Code anything. Do something ugly. Push it to production. Feel the pain of seeing it falling apart when your first users input some unexpected data or use it in a very, very silly way. Dig your way though the logs. Understand what's going on. Fix it. Make it better. Make it more ergonomic so people use it correctly without you telling them. Repeat the cycle as fast as possible. Accumulate experience.

Development is not like tennis or ping-pong (sorry). It's an art. And there are no straight do or don't out there. Just a bunch of principles and recommendantions that you should always take with a pinch of salt. At the end of the day, those architecture gurus are not there on a late saturday night when you're debugging your app.

While programming is little more than talking to the machine, development is another level. It's a communication, a dance, between machines, people, businesses, structures, infrastructures. It's debatable one can ever find an axiomatic truth about what makes a good software. It's like trying to define once and for all what's good dancing 💃

If you think I'm wrong, then I suggest you write down your findings in a methology book on "How to deliver value with certainty using software." You're a guaranteed billionaire overnight 😂

All that said, I mostly agree with Tyler and just wanted to have some fun here 🙃 Have a good one and follow me if you'd like to know more on how to improve your coding game 😎

Collapse
 
thawkin3 profile image
Tyler Hawkins • Edited

Thank you Benjamin for the thoughtful reply!

I love the Niels Bohr quote and wholeheartedly agree with it and with your summary of it:

Get out there. Code something. Code anything. Do something ugly. Push it to production. Feel the pain of seeing it falling apart when your first users input some unexpected data or use it in a very, very silly way. Dig your way though the logs. Understand what's going on. Fix it. Make it better. Make it more ergonomic so people use it correctly without you telling them. Repeat the cycle as fast as possible. Accumulate experience.

Correct me if I'm wrong, but I think we are definitely mostly agreed here, saying the same thing but in slightly different ways. Trying and failing and gaining experience is a valuable thing. And then, we learn from these mistakes. After feeling the pain of our code breaking in production, we learn these lessons and apply them consistently.

Taking your example, maybe the user entered some unexpected input which broke the app, so now you as the developer have learned that you should write code that can fail gracefully or that can handle bad input. You've learned to write better unit tests (or maybe you didn't write any tests at all! 😱). You've learned to think about more than just the happy path and to think about how things can fail. And hopefully you've documented this knowledge somewhere that you can frequently refer to it so that you don't make these mistakes again.

So in short, through your experience, you learn to stop making the mistakes in which you've previously defeated yourself. You figure out how to play the loser's game.

P.S. I'm not sure if you've ever read Michael Lopp's essay on "Stables and Volatiles", but based on some of the ideas you've expressed I think you would really enjoy it: randsinrepose.com/archives/stables... 😄

Collapse
 
bdelespierre profile image
Benjamin Delespierre • Edited

P.S. I'm not sure if you've ever read Michael Lopp's essay on "Stables and Volatiles", but based on some of the ideas you've expressed I think you would really enjoy it: randsinrepose.com/archives/stables... 😄

Thanks a bunch, I'll have a look 👀

Correct me if I'm wrong, but I think we are definitely mostly agreed here

You are not wrong. I might add that pain is, IMHO, an essential component of the learning process. Trying to avoid it and staying in your comfort zone is perhaps the worst mistake you can make in that looser's game. One that will surely impede your growth and therefore, your ability to avoid making other mistakes.

A personnal example of mine is that I rejected automated testing until 2017, deeming them worthless and demeaning people who wrote them. Simply because I was afraid of subjecting my work to an objective standard of measurement 🥲

So, beat yourself up as much as you can tolerate 😅 Trust me, the payoff is huge.

Thread Thread
 
vberen profile image
Nicklas Wessel

I think developers are masochist.
We like the frustration of finding a solution to a problem, or debugging for hours (i mean, i hate it.. i hate that i somehow love it)

But damn, it is painful sometimes

Thread Thread
 
bdelespierre profile image
Benjamin Delespierre

Development is indeed an activity we love to hate 😂

Thread Thread
 
rorygren profile image
RoryGren

But the kick, oh that kick, after the hours of "losing" shots, seeing your artwork in the wild, handling everything users can throw at it...
Yeah. Worth it!
Thanks for the article. It's a good read!

Thread Thread
 
thawkin3 profile image
Tyler Hawkins

Added some clarification here! dev.to/thawkin3/comment/1iaka

Collapse
 
j0ldfield profile image
j0ldfield

That's a terrible article to write about haha. There is merit though

Collapse
 
thawkin3 profile image
Tyler Hawkins

Tell me more!

Collapse
 
justintrang profile image
Justin Trang

I like your way of thinking - but I dont agree with you.

Stop making error, or making less error won't help you win the game.
It also depends on how you define "the game", but I believe it's more important to learn form your errors and dont make them again.

Collapse
 
thawkin3 profile image
Tyler Hawkins

Tell me more!

I don't think I'm understanding your statement here though. Isn't "stop making errors, or making less errors" (my words) the same thing as "learn from your errors and don't make them again" (your words)?

Collapse
 
justintrang profile image
Justin Trang

I think "stop making errors" sometime stop you take risks.
Personally I think it's ok to try and fail, and learn from your mistakes

Thread Thread
 
thawkin3 profile image
Tyler Hawkins

Gotcha, thank you for clarifying! Yes, this is a great point. We absolutely should continue to innovate and try new things and not be afraid to fail.

So maybe something I should help clarify is that when I talk about learning to stop making unforced errors, I don't mean to stop taking risks. Professionals in any field still make mistakes, and no one is infallible.

But thinking back to the analogy of amateur tennis vs. professional tennis, if we can learn from our past mistakes and stop hitting the ball into the net repeatedly, I think that is a good thing. As an experienced developer innovates and explores and takes risks, they would still be wise to apply lessons they've learned in the past so that they don't repeat the mistakes that they've made early on in their career.

Thread Thread
 
thawkin3 profile image
Tyler Hawkins

Added some general clarification here since I'm seeing a recurring theme in some of these comments! dev.to/thawkin3/comment/1iaka

Collapse
 
lgcallejask profile image
lgcallejask

I really enjoyed reading this short article. Thank a lot for sharing!

Collapse
 
thawkin3 profile image
Tyler Hawkins

Thank you for reading!

Collapse
 
exoticallisticsm profile image
Salieu Sesay

The article is really well written.

I really appreciate the insight and pointers to become a better coder, while also avoiding careless mistakes that make coding more difficult than it already is.

Thanks Tyler, and Cheers...🥂

Collapse
 
thawkin3 profile image
Tyler Hawkins

Thank you Salieu!

Collapse
 
dvddpl profile image
Davide de Paolis • Edited

Loved this article. and loved the parallel with Ping Pong.
I always found that we developers have a tendency of
shoot ourselves in the foot by underestimating tasks, overengineering solutions or simply by focusing on wrong things ( cure the symptom of a problem and not solve the root cause).

Expecially loved you list of unforced errors and i could not stress more on the first one:

Not understanding the problem before trying to code a solution

Too many time I have seen team members diving head first into coding something without previously properly thinking about the problem, understanding the context and the scope, coming up with a couple of alternatives and discussing them with other peers, and instead find themselves with a rejected merge request days or weeks later..
Thanks for sharing

Collapse
 
thawkin3 profile image
Tyler Hawkins

Thank you Davide! Those are some great additional items you've identified to add to our list of unforced errors.

Collapse
 
rmadhuram profile image
Raj Madhuram

Nice article! I was reflecting a bit on who is the opponent here: We often fight tight deadlines, shifting business requirements, ever changing technology landscape, losing talent to competitors etc.

Although there is truth to this article's assertion, I believe the opponent's tactics is also a big factor!

Collapse
 
dedhammaman profile image
dedhammaman

I smell perfectionism in this article, which has invaded the industry of developers. It's good to do these things, but not the end of the world if mistakes are still made, which they are.

Collapse
 
thawkin3 profile image
Tyler Hawkins

Added some clarification here: dev.to/thawkin3/comment/1iaka

Collapse
 
thawkin3 profile image
Tyler Hawkins

Perfectionism, no. But growth, self-improvement, and ownership, yes!

Collapse
 
jaygcoder2020 profile image
Jay G

Couldn't agree more. I think it's a lesson too on what to automate/delegate; admittedly people are afraid of automating too many things, but sometimes they're worth doing. One less bullet to soot you in the foot later.

Now on the code review side, things can get pretty dicey when people have different ways/ideas of doing stuff. That said, keeping it as simple as possible works wonders. Simple = less mistakes (typically), plus they're easy to test.

Collapse
 
thawkin3 profile image
Tyler Hawkins

Good insight! Yes, when it comes to code reviews, it's important to remember that humans are involved in the process, and humans can be irrational and emotional creatures. 😅

These are some of my favorite articles when it comes to having productive code reviews:

Collapse
 
ndrone profile image
Nicholas Drone

I think it really depends on what side of the coin you look at. In your analogy with the professional players. If one player, places his shots all over the court did I really win based on skill, or did I just tire out my opponent by placing him in a stressful overworked situation enough that he started to make mistakes, and beating themselves. Playing back to the losers game.

I believe software engineering is very similar. Most of us are put in stressful situations, to where we believe we need to move fast. Applying stress, and having to rush is where mistakes are made.

Where software engineering becomes a winners game, is when we have a voice. When we can push back on a timeline. When we can ship the product when it's done. Move at a speed that matters.

Collapse
 
thawkin3 profile image
Tyler Hawkins

Absolutely! Outside pressures can cause us to make mistakes as we rush to get code out the door. Having a voice, working under reasonable deadlines, and working in a psychologically safe environment are all crucial factors to success that you've identified.

Collapse
 
z2lai profile image
z2lai • Edited

Interesting introduction to this concept of loser's game! What I took away from this is:
In tennis, to win the losers game, you need to know the basics to avoid unforced errors which is hitting the ball over the net and inside the court. Whereas in software engineering, the basics aren't just those couple of things, but rather that huge list that you wrote in the article:

  • understanding the problem before trying to code a solution
  • understanding the tools or programming languages we use
  • carefully reviewing our own code before asking for a code review
  • manually testing our own code before asking for a code review
  • writing unit tests
  • following agreed-upon company standards

So it looks like I have a lot of basics to consider to avoid those unforced errors before I can even consider myself an 'amateur' that's winning the losers game.