0% found this document useful (0 votes)
63 views91 pages

Yellow

The document discusses principles for software development. It talks about how being fearless or terrified are both dangerous qualities for developers. Fear is a useful signal that should be listened to but not necessarily obeyed. It also discusses how just-in-time research is better than trying to keep up with all software development news and changes, and how developers should only research what they need for current projects rather than trying to learn everything.

Uploaded by

FVR
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
63 views91 pages

Yellow

The document discusses principles for software development. It talks about how being fearless or terrified are both dangerous qualities for developers. Fear is a useful signal that should be listened to but not necessarily obeyed. It also discusses how just-in-time research is better than trying to keep up with all software development news and changes, and how developers should only research what they need for current projects rather than trying to learn everything.

Uploaded by

FVR
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 91

YELLOW

YELLOW
Principles (or useless aphorisms) for software dev

Baldur Bjarnason
© 2023 Baldur Bjarnason
All rights reserved
Published in Hveragerði, Iceland
Typeset in the Literata typeface
CONTENTS
YELLOW........................................................................................... 6
1. Introduction .......................................................................... 9
2. Fear is a signal ....................................................................... 13
3. Just-in-time research ............................................................. 17
4. Technology changes slower than you think ............................... 21
5. Always maximise your understanding ..................................... 25
6. Gall’s Law ............................................................................ 29
7. Analogue ............................................................................. 33
8. Don’t tinker ......................................................................... 37
9. Correct and incorrect ............................................................. 41
10. Loose coupling ..................................................................... 45
11. Widely used standards........................................................... 49
12. Premature optimisation ........................................................ 53
13. Avoid state management ........................................................ 57
14. UX bugs versus complexity ..................................................... 61
15. The two questions ................................................................. 65
16. Don’t try to solve every problem ............................................. 69
17. Throwaway prototypes .......................................................... 73
18. Don’t be a correctness bully.................................................... 77
19. Worse is better, but it’s also how we got into this mess ................ 81
20. Yellow ................................................................................. 87
YELLOW
INTRODUCTION
Introduction

This is Yellow: Principles (or useless aphorisms) for software dev.


Laying out “the rules” or “how it should be” has been a popular pas‐
time among intellectuals and posers alike through the ages.
These sorts of projects that aim to pull together pithy ideas and
single sentence quotes explaining how the truths of how we work, and
if you just do this one thing everything will be fantastic.
They are mostly useless, but I’m hoping that this will be at least
somewhat useful.
If it doesn’t teach you something new then I hope that it supports
the correct ideas that you have about the world.
Those ideas obviously being correct because, you know, if you agree
with me then you have to be right, right?
This is an experiment on my part.
I’m trying something new to see if this is helpful to people. This
ebook began as transcripts of a series of videos.
The videos themselves are probably useful to some. Text can some‐
times be like a wall that separates you from the meaning that you’re
trying to find in it. Sometimes having a voice, something human that
plays in your ear, can be helpful to sort of emotionally ground the
ideas and sort of guide you through them.
But narration is also a classic tool for writing. A way to cut through
blocks and hesitation.
The idea for the videos was inspired by Derek Jarman’s Blue, al‐
though my motivation is obviously not as dire and depressing as his, as

10
Yellow

he made his movie entirely a blue screen with incredibly well-con‐


structed audio track because he was turning blind from AIDS.
It was a way for him to finish the tasks that he felt the world had set
to him.
This is the same, just less horrible. It’s a way for me to see if I can get
the ideas I have out there with different kinds of work, using methods
I can use at different times when I don’t have the focus to write, when I
don’t have the focus to construct a more intricately structured text or
a book and can instead bring you something through different means
to make sure that my time is used more productively.
So yeah, I definitely stole the idea from a dying man.
I don’t feel guilty about it because I’m hoping that you’re going to
go and watch his movie as a result.
It’s available on YouTube, amazingly enough, in stereo.
It has to be in stereo.
It’s a great film.
Go watch it. Then come back. If you feel like it.

11
FEAR IS A SIGNAL
Fear is a signal

One of the worst things you can be as a software developer is fearless.


The other worst thing you can be is terrified all the time.
In the early days of my career, I was working at a company that had
a culture of constant paranoia, a hyper-awareness of all the possibilit‐
ies of attacks and failures, and it resulted in a certain level of paralysis.
Admittedly, they were an anti-malware company, so they were con‐
stantly under attack.
But it left the organisation in a place where’s no way that anybody
could get any web-facing project done or shipped at a reasonable pace.
Everything was walled off, separated, made sure that it wouldn’t
break or interrupt or expose them in any way.
The core of their e-commerce system was built in C because their
main web developer at the time was hyper-paranoid about the possib‐
ility of something dubious sneaking in through the back door of a
scripting language.
This is at least a few steps beyond a normal level of worry.
This was back in the day when scripting languages were considered
to be young and immature.
Python was a new idea.
Most of the web was still being built in using Perl CGI scripts.
PHP was even a relative novelty to many companies.
The developer decided to use C.
When I arrived, he had long since left and possibly not coincident‐
ally had a nervous breakdown. Last I heard he had died in a freezer-

14
Yellow

fire while working in the kitchen of a restaurant somewhere in Scand‐


inavia. Either Sweden or Norway, I forget.
We, however, were locked in this e-commerce system that had a
core built in C that spoke to templates rendered using Perl CGI-BIN
scripts and every suggestion to change anything was met with fear.
It took close to a decade to actually replace that core system.
And what replaced it was almost definitely not good.
It was a mediocre hack job splicing custom, proprietary features
into an open source e-commerce system.
But it was a substantial improvement over an archaic, ancient pile
of C code that nobody could understand.
That was possibly the most extreme example of paranoia or fear
crippling your software development efforts.
But it’s not the only one I’ve encountered.
The other one, the utter fearlessness, is possibly just as bad. At the
same company later on, after its culture had shifted a bit, one of the
go-to guys to get things done was this developer who was absolutely
unafraid of anything, trying anything, implementing anything, and
he would have a go at whatever. He’d complain first. Loudly. Then he’d
talk himself into doing it. Out loud.
He was quite possibly, in a fear-laden company, the only one who al‐
ways tried to get things done.
But the same errors kept cropping up. He bit off more than he could
chew and even when he managed to succeed, it resulted in software
that was not good, not safe, and quite hard to deal with.
So, fearless and terrified are both incredibly dangerous qualities in
a software developer.
And the thing to remember is that fear is a signal.
That’s what most emotions are.
Fear is a signal that you have to learn to listen to.
You have to learn to consider it a warning, not necessarily a guide.
It’s like a compass tells you where north is. Having a compass doesn’t
mean you’re obliged to always be heading north.

15
Fear is a signal

Knowing where danger lies, knowing what areas of your project


cause you anxiety, cause you stress and worry is extraordinarily use‐
ful.
Sometimes it means you need to actually go there and try to address
the problem. Sometimes it means you need to avoid it.
But without that signal, if you don’t have any fear, if you don’t have
the signal that fear gives you, then you are effectively lost.
You’re going to stumble into danger.
Things will get complicated.
The same applies to being terrified all the time.
You just get locked in at home or in a single corner.
You never get anything done.
Nothing interesting gets shipped.
Ambition goes out the window.
Fear and fearlessness, the extremes are both very bad.
You need to just treat it as a signal and listen to it, but not obey it.

16
JUST-IN-TIME
RESEARCH
Just-in-time research

Just-in-time research will always beat trying to keep up with the web
development or the software development news treadmill.
This is a mistake I keep doing or have kept doing throughout my ca‐
reer, but I’m not a lone in that. It seems to be the norm in the industry.
We follow everybody who seems to know anything on social media;
we follow all the websites; we keep up with all the aggregators; we
overwhelm ourselves with noise every single day; and we keep trying
to remember all the little details and nuggets and new APIs and func‐
tion signatures.
Who is genuinely going to remember the exact way an object, a
standard API is constructed or how a standard function that comes
with a platform is called?
Our memory is fallible, it’s just how humans operate.
It might work as a tactic when you’re in your early 20s and your
memory is at peak efficiency but as you continue to age and your
memory degrades you will feel a deterioration in your abilities, be‐
cause you’ve built your entire method of working on something that is
not going to work forever.
It’s not sustainable in any way.
The only realistic alternative, the only option we all have if you
want to have a long-term career and not just give up once we reach our
30s or 40s is to just do the research just in time as you need it.
If you are making a web form, then that’s the time to look into the
form APIs.

18
Yellow

If you’re starting to work on an app, then that’s the time for you to
sit down and do research into the specific needs of that application.
Then you apply what you’ve just recently learned while it’s fresh in
your memory. Using something shortly after you’ve first encountered
it helps integrate it, and you’re much more likely to remember it that
way.
Things you use are much more likely to stick in your mind.
If you apply information while it’s still fresh in your mind you will
almost certainly remember it.
You might not even remember it as a fact.
It might not even go into your semantic memory of information
and content nuggets or trivia.
It might just end up as muscle memory. As something you end up
typing automatically without thinking about it.
That’s the best kind of learning when you’re working because it’s
something you don’t have to think about. You don’t have to recall. It
becomes almost like a mechanized feature like a snippet that you’ve
got built into your code editor.
Emphasize just-in-time research.
Try to read and learn things just before you actually use them be‐
cause then you’re much more likely to remember them, and then
you’re much more likely to integrate them into just the basic way of
how you work.
If you keep trying to follow everything, follow every update, every
new feature, every feature in development, every proposed specifica‐
tion, you will get overwhelmed.
You’ll get burnt out, and you will just have to give up.
It will not work.
It is not a strategy that will give you a long and healthy career.
Learning – proper learning – which involves a cycle of reading, us‐
ing and integrating, is the only way.
It’s the only sustainable way.
The rest is just fashion, just pop culture.
If you do follow all of the updates, the discourse, the news items as
entertainment, as the kind of gossip that you follow the same way you

19
Just-in-time research

follow celebrity news or even like they did with the old days of Valley‐
wag.
If you think of it as entertaining industry gossip, then yeah, that’s
fine.
That’s entertainment.
You don’t expect yourself to remember who slept with who while
shooting a movie 10 years ago.
You shouldn’t expect yourself to remember a random detail of a
specification that was proposed but never implemented five years ago.
Read as you need it, use it, and then you’re more likely to remem‐
ber.

20
TECHNOLOGY
CHANGES SLOWER
THAN YOU THINK
Technology changes slower than you think

Technology changes much more slowly than you think.


This might seem like an almost heretical notion, considering
everything that’s changed becomes of technology in the past 20 years.
Much of it revolutionary, to reuse a word that Silicon Valley and the
tech industry is fond of. They’re more fond of “disruptive”, for some
reason, but overall the technology doesn’t actually change that fast
any more.
At least not in the past five, six, seven years. The big changes in the
past few years have been political, environmental, economic.
Scale. Scale changes, but not the underlying technology.
The tech of the tech industry has been evolving, but with fewer of
these revolutionary or paradigmatic changes that we used to see.
Chips have been getting faster at a slower pace.
We haven’t seen any fundamental structural change in the in‐
dustry.
The same companies that were oligopolies or monopolies 10 years
ago are dominant today.
The software, the applications, the operating systems that were
dominant a decade ago are still dominant today.
There have been very few new dramatic changes in how we use
computing machines since the touch screen, since the phone popular‐
ized the touch screen.
These things aren’t changing as fast as you think.

22
Yellow

And this applies even more on the sort of granular level that we
work on in terms of software development.
We keep hearing about updates, about API changes, new features,
and new standards, but quite a few of these don’t actually ship, espe‐
cially on the web.
But more importantly, most of the noise that we hear is repetitive.
We hear about a proposal, and we hear about the change to the pro‐
posal.
We hear about another change to the proposal.
We hear about an alteration, about an update.
Our minds interpret it as a series of changes, when what actually
ships and is usable is just one thing. We’ve turned a single shipping
change that would be easy for us to follow into a noisy stream of up‐
dates that we can’t handle.
If you step back and follow just the aspects of these news updates
that you’re likely to be able to use in a software development project,
none of it actually happened in a real way.
Until it ships, it’s gossip.
Until it ships to enough people to make it usable, it’s gossip.
You don’t have to follow news about it
It doesn’t really matter because the feature might not actually ever
get enough of a critical mass of users for you to ever be able to rely on
it.
Much of the software development space is operating at a much
slower pace, a human pace, that we can actually step back and have
the luxury of waiting for.
We have the luxury to wait and see if something gets adopted by
people.
And that’s a human-scale time thing, if you pardon the word mess.
That’s not happening at the light speed everybody says tech oper‐
ates at.
Most of the concrete changes that you actually have to pay atten‐
tion to happen at a human scale, at a human pace, that matches our
own pace, that matches your or mine.
It’s not as much of a struggle for us to keep up with that.

23
Technology changes slower than you think

We can actually step back and relax a little bit.


Let things just happen and then catch up without losing much, if
anything at all.

Note on Generative “AI”


If your reaction to the above is to ask “what about generative AI?”
then my answer is simple.
I said what I said.

24
ALWAYS MAXIMISE
YOUR
UNDERSTANDING
Always maximise your understanding

Every decision you make when you’re working on a software project


should be about maximising your understanding of that project.
We often make the mistake of having muddled priorities when
we’re structuring and organising our work on a software project.
We have these issues of career; we have internal politics; we have
the deadlines that we need to meet for each quarter; we have so much
weighing on us that it becomes much harder, it becomes actually hard
for most of us to come up with a humane order of priorities – one that
both works for the project in the long and short term and works for us
as people who need to be able to function as a part of the organisation
or the software development project.
One rubric or measuring gauge or guide, or what you want to call it,
that you can use to direct your work and your decisions is that one of
the biggest issues in any given software project is a lack of understand‐
ing of how it works as a whole system, a lack of understanding of how
a component works, a lack of understanding of which bits of it mean
what.
That’s the wall that separates us from being able to ship a project
that works for everybody. That’s the thing that we need to break
through. We need to constantly be mindful of the fact that the
primary thing preventing us from shipping, adding new features, fix‐
ing bugs, making the project better in pretty much any given way is a
lack of understanding.

26
Yellow

If we have that as a guiding question, as a guiding rule throughout


our work, we end up with more understanding, and fewer blocks pre‐
venting us from improving the project.
It’s silly to say this, it sounds facile and ridiculous, but this isn’t
how we organise our projects today.
We just pile things on; we ship and we ship; we add features; we
throw more things into the pot and we boil it; we use frameworks we
don’t understand, whose internals are just mysteries; we use depend‐
encies that update at a chaotic cadence; we just fill our projects with
stuff we don’t understand, with things that just are completely beyond
us and are just separate from us – walled off from us.
We get lost.
Our projects become utter mysteries. Of course they’re going to be
buggy, of course they’re going to fail, of course they’re going to be
sometimes even catastrophic for the end user.
That’s the norm.
It sounds ridiculous once you describe it in these terms that this
should be the norm. But it is, but it shouldn’t be.
Every single decision we make, whether it’s choosing our depend‐
encies, the frameworks, how we write our code, how we test the pro‐
ject, how we ship it, all the boilerplate should be about maximizing
our understanding of the project in its entirety. But instead we’re ask‐
ing generative models to spew out spaghetti code that we have no
chance in hell to understand any time, at any given moment.
We fill our projects with contexts and dependencies and ideas that
we have no hope of ever understanding.
Then we ship it to the end user who always manages to either find a
creative way to break it, or, which is increasingly more common, dis‐
covers that the project itself is finding creative ways of breaking them
and their work.
Because that’s the harm we’re doing.
We are disrupting people’s work.
We are, in shipping these projects, actively harming the world.
That’s tragic.
That’s a tragic thing to be a part of.

27
Always maximise your understanding

I definitely wish that were more easily avoidable.


But it doesn’t look like it is.

28
GALL’S LAW
Gall’s Law

One of my favourite laws – one of those principles that seem to be uni‐


versally applicable – is Gall’s Law. People who have worked with me in
the past are probably very tired of hearing about it.
John Gall was an author, scholar and researcher who focused on
systems and systems theory, and he wrote a very famous book called
Systemantics back in 1975 – it’s been updated, it’s available today as the
Systems Bible.
The Systems Bible is, on the whole, absolutely brilliant.
I recommend it.
Everybody who works in software should read it and be filled with
despair. Because it will fill you with despair. You will recognise
everything written in this text from 1975, to your horror.
One of the most long-lived and popular – or infamous, if you’re so
inclined – adages or rules from his book is what’s been coined Gall’s
Law. It goes as follows:

A complex system that works is invariably found to have evolved


from a simple system that worked.
A complex system designed from scratch never works and can‐
not be patched up to make it work.
You have to start over with a working, simple system.
Systemantics

In my experience, this is a universal rule.

30
Yellow

I have never seen anybody manage to break John Gall’s Law. It ap‐
plies to every single aspect of software development, in that we are
fond of planning and organising and building complex systems from
scratch. We design these intricate structures of objects and classes that
interact. We build things that have no chance ever of working.
Instead, the alternative that I always advocate is to try to bake evol‐
ution into your design. It’s fine to have a complex system design that
you’re aiming for in the long term, but you need to have a clear idea of
how it will evolve from a simple system that works to a complex sys‐
tem that works.
You cannot leap straight into the complex system.
You have to start small.
This applies to every system and subsystem in a software develop‐
ment project, whether it’s a feature or a module or the app itself.
Start with a single system, simple one that works, then you evolve
and add to it. If you’re adding a new feature, then it has to be a simple,
single thing that works from the beginning, and then you build from
there.
If you’re making an app, make a simple, bare bones, flawed but
working app. It can be flawed in that parts of it are obviously missing.
It can be flawed in that it’s ugly.
But the systematic aspect of it, the code, that needs to be working,
and it needs to be simple.
This is the only way to make working software, but it’s also a rarity.
It’s the exception. I have almost never been able to convince a man‐
ager that we should do it.
I’ve convinced them that they should do this, but they’ve never ac‐
tually accepted it in practice.
They say, yeah, absolutely.
I believe in a minimum viable product.
But then they keep adding things to what constitutes the minim‐
um, and they don’t realise that MVP is not the simple system that John
Gall is talking about.
The simple system does not have to be shipped.

31
Gall’s Law

It just has to exist as the foundation that you build on. But they
don’t really get that when they’re managing the project.
In the story, feature, or point breakdowns I’ve seen, it’s clear they
don’t understand the systematic aspect of it.
They almost always start with this vision of a complex interlocking
thing we’re just colouring in the numbers for.
They don’t grow the system.
They don’t grow the software.
There are exceptions, and those are great projects and great places
to work in.
But all too often, there’s a fundamental misunderstanding of how a
software system works on the part of the managers or the executives
of the projects that I’ve worked on.
I suspect that the same applies to everybody who’s listening to this.

32
ANALOGUE
Analogue

Here’s a controversial take from somebody who works in software and


the software industry. Analogue tools are sometimes better, faster and
cheaper than anything digital.
You see this quite often in design work in that a post-it and a pen
and a wall is cheaper and faster and more effective than pretty much
any collaborative application or digital whiteboard you can find.
The problem with analogue is it does not abstract location. That’s
pretty much the core advantage of digital over analogue. It lets you ab‐
stract location away.
The irony is that companies tend to choose the worst of both
worlds. They tend to use digital tools that are generally slower, harder
to use, more complex, more expensive and often fundamentally
flawed, but are designed to enable people from all over the world to
collaborate.
Then they ask everybody to come in and work from the office.
If you’re going to spend the money of having an office and put
everybody in the office, you should at least have the decency to use the
cheaper, faster and more effective analogue tools that you can use
when you aren’t working in a distributed organization.
Hybrid methods only give you the worst of both worlds.
That they’re doing both, which is just maximizing the cost of the
company to no effect, tells us there’s effectively no manager in exist‐
ence who actually pays attention to the balance book – the actual costs
and returns on investment in their organization.

34
Yellow

All of which is to say post-its are amazing.


Notepads are great.
Pens, you can get great gel pens for incredibly little money.
Whiteboards are cheap. A good one will last forever.
You can even get those cheap plastic sheets that you put over the
windows and walls. They’re ugly, but they work.
These things are faster than pretty much any collaborative tool you
can get in digital.
And we should not downplay their effectiveness.
Most digital note-taking tools are less effective.
For a normal person who’s doing a normal job, most note-taking
tools are less effective than a legal pad or a box of stack of index cards
and a pencil.
Because a stack of index cards and a pencil is an awesome tool.
It’s an amazing organizational and note-taking tool.
We – the software industry, that is – just isn’t aware. We don’t seem
to be aware as an industry that this is our competition.
Because if you speak with people who work outside of software,
outside of tech, they’re using the post-its. They’re using the legal pads
and the index cards.
They’re writing things down on pen and paper.
Their managers might buy Microsoft’s shitty collaborative tools in
remote learning and they, believe me, are cursing every time they’re
forced to use it.
We’re turning our life’s work – the collaborative tools, the software
projects that we make – into a sort of productivity tax that just is auto‐
matically bought by organizations and companies all over the world,
even our own, because that’s what you’re supposed to do and it doesn’t
result in the benefit we think it does.
What I mean to say is that we should try to use analogue tools when
we are in a position to do so. Don’t buy massively complex collaborat‐
ive tools or collaborative software that you don’t need to buy.
Most of it’s just a mess.

35
Analogue

Even the stuff that you love because, gee whiz, it’s such an innovat‐
ive example of CRDTs or Operational Transformation or some techno‐
logical whiz-bang thing.
The actual benefit it provides to people who use it is probably much,
much less than the joy of novelty is giving you.

36
DON’T TINKER
Don’t tinker

Don’t tinker.
Tinkering is endemic to, well, businesses everywhere, in that we
make a decision, we see the results, then we change what we did and
see another result. Repeat until you’ve got a mess.
What’s happening when we do that, generally speaking, is the first
decision had a margin of error: the role that randomness, environ‐
ment, and systemic variation played in the result.
Then we look at that result and assume that it was somewhat de‐
terministic or more deterministic than it was, but our change expands
the margin of error. We add the margin of error of the new experi‐
ment – our change – to the margin of error of the first experiment.
We’re even further away from understanding what was happening in
the first experiment.
The margin of error expands because we don’t know in which direc‐
tion any of it is swinging.
What we’re doing when we tinker with a system, when we tinker
with a project and update it as we do, is we are increasing the random‐
ness and obfuscating the facts.
We are blinding ourselves to what’s actually happening. We’re
blinding ourselves with noise.
The common way to counteract this is with A/B tests.
Those don’t really work either.
When done correctly, they are useful for establishing a local max‐
ima. That is, from the starting point, the sort of local optimum for

38
Yellow

how this button or this widget is likely to work. In a complex system,


local maxima are quite often utterly meaningless. It’s like obsessing
about how quickly you can screw in a single screw while putting to‐
gether an Ikea cabinet. Microsecond variations in a single fixture
doesn’t matter if you aren’t paying attention to the instructions.
We almost never know whether the A/B test is actually valid –
whether it’s genuinely meaningful.
We don’t know whether it has validity in terms of proving or dis‐
proving a thesis or idea we have about how the system operates.
We could just end up being tinkering again, in that we are watching
random changes in the system as a whole, and those random changes
can look statistically valid if the test is bounded enough and limited
enough in scope.
It can look like we are steadily testing ourselves in a structured way
towards a known goal. Then when we look back a year later and take
together the developments all the A/B tests have given us, and we find
that we’re in the same place as we started, statistically, we might turn
out to have the same conversion rates, the same level of interaction,
the same prices and the same sort of revenue from the users. A year of
tinkering with no improvement.
Trying to stop tinkering is hard because it feels productive, it feels
like you’re learning something about how the system works, but you
need more structured experiments for that.
You need more understanding, you need different kinds of meas‐
urement, you need to lock down the aspects of the system that are in‐
troducing variation.
This is one of the reasons why management theory and academics
like Deming have been so focused on tinkering, because their core the‐
ory is that the most important job of any given manager or executive is
variability control.
As the more we lock down variability, the more we understand the
system or organisation we’re working with, the easier becomes for us
to do structured experiments and tests and be reasonably sure the res‐
ult is valid. Even when something is known to be extremely variable,
like if we know that this process is wildly erratic, that is useful in‐

39
Don’t tinker

formation because we then can account for that margin of error and
see what that introduces to the rest of the system.
But tinkering blindly, which is most of what we do, most of what
every manager I’ve ever worked with does, just makes you less aware
of what’s happening.
It’s no wonder – it isn’t a surprise that the end result is most soft‐
ware companies and most software projects are just failures. Because
throughout the project, the people who are supposed to minimise
variation and minimise randomness are actually just steadily increas‐
ing the noise levels and increasing the margin of error in all of our
data and measurements.
That’s no way to run an industry, but it happens to be the way we do
run ours.

40
CORRECT AND
INCORRECT
Correct and incorrect

If it’s at all possible, you should try to make sure that incorrect looks
different from correct.
This might sound obvious, but it’s generally not the practice. You
can see this pretty much throughout the software industry.
You have forms where invalid entries are basically indistinguish‐
able from valid until the absolute worst moment, when the user has
filled in the entire form and is about to submit it.
Our training material and education and documentation displays
incorrect examples, and they look identical to the correct examples,
and our memories aren’t perfect, they’re going to remember them
both.
Our minds are pattern matchers.
If the wrong thing looks exactly like the right thing, it’s going to
confuse us. If you in your training material keep showing how not to
code for a specific API, how not to use a specific function, as well as
how to use it, there’s a very good chance that what the reader is taking
away from it is the incorrect way.
That’s the way that they’ll remember when it actually comes to
working and using what you’ve told them.
And this is almost universal in our industry.
We take away all the signals that are supposed to help people.
We mix the wrong thing and the right thing and the errors and the
successful actions. It all looks the same, and it all looks like a muddle.
It all ends up being incredibly confusing for everybody involved: the

42
Yellow

end user, the software developer, the designer, the manager. We tend
to exist in a perpetual state of confusion.
The way we design our information space plays a big part of it.
We seem to be fine with it.
That’s the weird part.
It doesn’t seem to stop us.

43
LOOSE COUPLING
Loose coupling

Loose coupling done right can be a superpower. But it has to come


from the system that you’re using: the programming language, the
platform or the software system.
What do I mean with loose coupling?
The standard definition, the one that Wikipedia uses, defines it as
weakly associated components or dynamically associated compon‐
ents.
In practice, this means that the parts of any given software system
can be replaced without it affecting the whole.
That means standard contracts between objects, standard function
signatures. Loose coupling and a level of standardization go hand in
hand.
Alan Kay is pretty much one of the godfathers of software develop‐
ment – to his chagrin, mostly because he doesn’t like what software
development today looks like.
He prefers the term late binding or extreme late binding. He distin‐
guishes it from loose coupling where things are just not tightly
coupled together and can be swapped out. Late binding is more of a
design choice that the programming language or system makes to not
bind the objects until as late as possible, possibly just at the time when
they’re called.
This is how Smalltalk worked. It was a runtime image consisting of
a collection of objects in memory. And those objects communicated
through messages and the messaging was routed at the moment when

46
Yellow

it was called. That would be what he called extreme late binding. He


believed that object-oriented programming just did not work as a
concept unless you had extreme late binding. That if you have an ob‐
ject-oriented system, a mess of classes, and aren’t able to swap things
out and bind them at the absolute latest minute, it will create an intric‐
ate, interconnected and fragile system that will break in a cascading
fashion as soon as you start to modify something in the wrong way.
We always modify things in the wrong way first.
That’s just how it works.
So, having extreme late binding or loose coupling is a kind of super‐
power because it lets you create a system that adjusts itself on the fly
while it’s being run, that is inspectable, that you can investigate. It
means that components tend to be cheaper to work on because you
can swap them out for ready-made ones.
If possible, you can then swap back in a custom one that will seam‐
lessly interact with the rest. And all of that lowers cost. We generally
don’t have systems that do this well in software development.
Well, they’re available – there’s plenty of them.
But the common platforms that are used in production and the
ones that we are hired to work on, that we get paid to use, they tend to
be early bound.
They’re compiled, although that’s not necessarily a sign of early
binding.
Like Objective-C, the programming language that is pretty much
the reason why the Mac OS is still alive today. It’s what saved theplat‐
form during the lean years when there was nothing, when developer
interest from big software companies died down and indie developers
had to step up. Without Objective-C, they would not have been able to
ship all the incredibly valuable and useful software apps that they did
and Mac OS X would have died – guaranteed stone-cold dead.
Objective-C made these programmers much more productive be‐
cause even though it was compiled, it had a runtime, a messaging sys‐
tem that gave it an effect of late binding, even though it had the speed
and performance of an early bound C++ type of language.

47
Loose coupling

JavaScript has elements of the same, but it also is extremely flawed.


Probably even more flawed than Objective-C
As we all know, JavaScript has its issues.
The way we do JavaScript today very much undermines its ability to
do late binding because we do bundle and bind everything and com‐
pile and make sure that things are as inflexible as possible.
But the language has potential and that potential is increasing
every year with things like import maps and proxies and a variety of
other tools that are being added to the language to give us this power,
should we choose to use this.
I think we should.
I don’t think we will. Not in a constructive way.
But I think we should.

48
WIDELY USED
STANDARDS
Widely used standards

A topic related to late binding or loose coupling. As a general rule, you


should always prefer widely used standards, over widely used conven‐
tions, over seldom used standards, over the arbitrary shit somebody
claims is standard practice.
What I mean by that is HTTP and RESTful APIs are standard.
They are something that you’re going to find is available pretty
much everywhere.
It will work with pretty much every web server framework.
It will work with every client.
It will work with every browser today.
Didn’t work always back in the Internet Explorer days, but we’re
long past that.
GraphQL might be a standard practice in some circles, but it is just,
to reuse the phrase I used earlier, arbitrary shit.
It is not a standard. It is cosplaying a standard.
Even if it gets standardized, in the big picture of the overall web de‐
velopment industry it would become a seldom used standard because
the enterprise organizations and the startups that love it are not the
world. GraphQL is just another SOAP.
They are a niche in the bigger picture of software development.
They think they are the world, but they’re not.
Also, GraphQL is likely to fade in popularity because elements of it
are a fad.

50
Yellow

It’s useful sometimes – there are aspects of GraphQL that were


genuinely interesting and useful for specific tasks, but it’s still a fad
nonetheless.
Things can be both useful and fashion.
But once something becomes a fashion trend or a fad in the soft‐
ware industry, that’s going to overwhelm the practical use.
Once the fad runs out, the practical aspects of it will suffer.
That’s why you should avoid the arbitrary shit that somebody
claims is standard practice.
The stuff in between the widely used standards like HTML, stand‐
ard DOM APIs, HTTP, and the other core foundations of what we work
with, the other parts like the widely used conventions and the seldom
used standards, those get a bit trickier. The seldom used standards are
probably easier to identify.
Like XHTML2 or XHTML might have been a standard, and a lot of
the stuff that came out of the XML era of the W3C were standards, but
they weren’t really that broadly used because, you know, they were a
bit shit.
A widely used convention that might not be standardized is still
preferable over a seldom used standard.
The problem there is identifying the widely used convention and
their pitfalls.
The one that sort of immediately comes to mind is sort of standard
ways that Node uses to – or like a convention that Node web apps use to
identify arrays in URL encoded payloads. The whole bracket after the
property name feature. It’s still a bit error-prone occasionally.
If the choice is between that and a seldom used standard, you use
the convention. What you should use whenever you can is the widely
used standard.
Like multipart/form-data or serializing as JSON. That is actually
standardized and broadly supported.
You prioritize widely used standards, over widely used conven‐
tions, over seldom used standards, over the arbitrary shit people pre‐
tend is standard practice. If you use that order of priorities, you’re
generally going to have a much nicer time than if you keep chasing the

51
Widely used standards

fashion trends that people claim will be standard practice in the fu‐
ture.
Wait until it’s an actually widely used convention or a widely used
standard.
Until it is, ignore it and use something else.

52
PREMATURE
OPTIMISATION
Premature optimisation

Premature optimisation is a form of tight coupling or early binding,


generally speaking.
That’s why it’s usually the root of all evil.
It ties your system together in a brittle but highly optimised state.
If you start moving anything around, both the optimisations and
the system will often break. So if you’re going to optimise early, op‐
timise within a self-contained unit or self-contained object that is it‐
self loosely coupled with the rest of the system.
That way you can actually, if you want to, prematurely optimise.
The problem is that there’s a good chance it’s wasted work because
you don’t know what the performance of the system as a whole is go‐
ing to be.
Once you have a system that’s stable enough for you to start work‐
ing on the optimisations, then you run into the issue where you’re ba‐
sically tightening things up and connecting things more than you
should just to make things faster.
That’s one of the strategies for optimisation. You wire things more
tightly together because the dynamism that comes with a loosely
coupled system in and of itself has a performance cost.
But you can’t not optimise because that’s how we got into the mess
that we are in. We have a world full of really slow software that just
really hoover up every single performance increase in the hardware
that we have.
So we have to optimise somewhere.

54
Yellow

Those can be done on the one hand on the design stage.


As you’re designing and evolving the system, you can avoid the
things that you know are likely to be slow.
Then once you have a stable system, you can start to optimise the
individual units that are loosely coupled, and you can measure its im‐
pact on the system as a whole.
You can spot the specific modules and components or classes or ob‐
jects that are slowing the rest down.
If you’ve followed the guideline of using loose coupling, you can
swap them out for something more performant.
You can do that while making sure that you’re not tightening up
the connections between the components in the system so that you
still maintain the flexibility, the dynamism and the sort of long term
ease of use that you get with loose coupling.
So that’s why premature optimisation is the root of all evil.
Usually you can optimise early if you’re careful, but be warned,
you’re often working blind because you aren’t measuring the genuine
impact on the system as a whole.

55
AVOID STATE
MANAGEMENT
Avoid state management

Avoid managing state as much as you can, no matter what kind of soft‐
ware you’re making.
There’s a reason why the one universally applicable debugging or
problem-solving tool in software and computing is turning it off and
on again.
That’s because of state, in that we are incredibly bad at managing
state in our software and our code.
It clutters up, it gathers, it sort of grows like mould here and there.
Much of the time we might not even be aware that we’re letting a com‐
ponent build up state. Then it starts to go wrong because it interacts
with other components in ways that we just have no way of under‐
standing.
This is why we’re told we should always avoid side effects.
As in, if you’re writing a function, that function should not do any‐
thing except return data.
It should not modify its input, it should not modify global state.
It should just do something with its input and return data – return a
value based on what it’s called with.
The same applies to object-oriented programming.
A method should only modify the object it’s called on. The object
being the value or the data that’s effectively being “returned”.
This is state avoidance, and it’s absolutely necessary if we are to try
and make stable software. We are just not good at keeping to that rule.

58
Yellow

You look at web apps, operating systems, applications, native, elec‐


tron wrapped. They all just collect states like they’re being paid to do
so.
We seem to have no fear of it. If you look at any given web frame‐
work, for example, they tend to make states and state management
simple. They try to give you so many tools and mechanisms for man‐
aging state, we forget that our first tool is to not have any state if we
can avoid it.
We forget because there are so many nice hooks or other modules
that we use to manage the state.
Because of the wealth of tools that we’re given, we forget that our
first option, our first choice, is almost always not to use those tools or
state.
State management might be simplified, but it will still be the
biggest source of errors and bugs in your software.
There’s nothing else that comes even close to causing as many er‐
rors in your work, in the app, in what the end user sees as complex
state.
State management tools are great.
They do make the job easier.
But the first and most important decision is to try not to have any
state in the first place.

59
UX BUGS VERSUS
COMPLEXITY
UX bugs versus complexity

Bugs hurt the user experience more than complexity helps it.
What I mean with this is we need to think of the end user and the
software they’re using to do their job as an interlocking system.
They are working in concert to accomplish a task.
Back in the olden days, back in the early days of Mac Classic or in
the early days of Windows, of Office in the 90s, they actually measured
this as a whole, measured this as task completion, as, you know, the
user and software working in concert.
But we stopped doing that. Instead, we began to A/B test individual
features and lost sight of what the overall goal is for the end user, why
they are actually hiring this software for a job.
There’s a diminishing return on investment on added complexity
from the end user’s perspective.
The more complex the interface becomes, the more effort they have
to put in to get the same rewards that they used to when the interface
was simpler.
The complexity we introduce also causes bugs. Software develop‐
ment is generally bad at what it does as an industry: we keep increas‐
ing the complexity, which adds bugs, and those bugs are more harmful
on the whole than the benefit the end user gets from the added fea‐
tures. Complexity does not outweigh the harm that comes from the
bugs because the bugs are everywhere.
They are all over the place. If you have ever done studies where you
are on location, and you’re watching somebody in an office environ‐

62
Yellow

ment or try to buy something online – if you’re doing the kind of re‐
search that used to be the norm, you will notice that every single one
of these interfaces is just filled with bugs.
Users keep having to redo things.
They keep having to correct for errors.
These bugs are not just software flaws or software defects.
The defects in the user interface are bugs from the perspective of
the end user.
And because that’s the person who we’re supposed to serve, it
should also be a bug from our perspective.
Complex interfaces are just a breeding environment for user exper‐
ience and user interface bugs.
It’s also a breeding environment for regular old software defects.
That’s what complexity does to a project.
Bugs tend to lose people, cost you money, lose work and destroy
data.
But, from the perspective of the end user, it’s primarily a way of
making things harder, less accurate, slower.
This is the industry we’ve become.
We have become an industry that values complexity and features at
the expense of the end user, because we trust that they will buy – that
their manager or their sales department will buy the software – des‐
pite the fact that it works less well than earlier or simpler versions of
the software.
We can try to counteract it by simply keeping this in mind:
Complexity harms the end user.
The reason is that the bugs that complexity causes harm the user
experience more than the added features tend to.
If you keep that in mind, you’re usually in a better place to serve
the end user and create good software.
Although I do recognize that getting that past management is of‐
ten, shall we say, tricky.

63
THE TWO
QUESTIONS
The two questions

The two most important questions in software development are “what


do I need to do?” and “how do I know I’ve done it?”
These questions work on a more granular level than you’d expect
from something that sounds so simplistic.
“What do you need to do?” is the code you need to write. “How do
you know you’ve done it?” is a tricky question that quite often can
only be answered with a test.
This is why test -driven development is generally so effective.
In writing the test you answer both questions at the same time. You
are literally describing in code – in verifiable code that will run and ex‐
ecute – a plan for what you need to do, and you know that you’ve done
it because the test will pass.
So test-driven development is a way of answering the two core
questions of software development in the most cost-effective fashion
possible, because you almost never do added work when doing test-
driven development. You generally only do the work required to pass
the test, so the test defines the scope of the task.
If you lapse and you fall into the trap of doing the whole regular-
driven development without the tests, you tend to overwork. You tend
to do more than is necessary. Then when you write the test you have a
problem attaining decent test coverage because there’s just a bunch of
stuff in there you thought you needed to account for but isn’t being
used by the system or the software anywhere in your current tests.

66
Yellow

You both end up doing more work than you needed to do on the
component itself, and then you do more work than you needed to do
in writing the test afterwards. Then, because everything becomes
more complicated, you build up more bugs, more flaws, more com‐
plexity, there’s more need for documentation, there’s more need for
testing, there’s more need for quality assurance afterwards, you need
more end-to-end tests because the thing is bigger and more complex.
Test-driven development cuts through that. It is the simplest
strategy available to us for answering the core questions of software
development and generally speaking if somebody hands you a simple
solution to a complex problem, you take it.
It doesn’t matter if you have qualms about it or might have a heart‐
felt belief that somewhere out there, there might be a better solution
to the problem of software development. This is the best solution we
have, and it’s generally irresponsible to ignore that.

67
DON’T TRY TO SOLVE
EVERY PROBLEM
Don’t try to solve every problem

Absolutely do not try to solve every problem you can think of before
you really have to.
This ties in with the whole test-driven development thing. The test
defines the task you need to do, and you only do that task.
If there is a problem that comes up in the project or a bug, then you
write a test for that bug, and you write code that solves just that test.
A pitfall we all fall into is we tend to try and imagine all the possible
things that we might need, or the project might need – the future fea‐
tures we’ll need to add or integrate – and we tend to want to prepare
for this right at the beginning.
This doesn’t just add to our work. It does that too. It adds a massive
amount of work. If you look at the ratio of wasted work to actually
generally productive work in most software projects, it’s not going to
be as favourable as you’d like, because we keep solving problems we do
not have.
But this is also an issue because it leads us to build complex systems
from scratch. If you’ve paid any attention to Gall’s Law, you know
that’s not going to end well.
We keep imagining complex problems we don’t have yet, and we
keep designing complex solutions to those complex problems, which
require complex systems, and it leads us to just make something that’s
broken right out of the gate. This is why an effort to try and create
something more robust, something more reliable, often backfires.
We’ve created a complexity hell that is more broken.

70
Yellow

It’s less likely to work.


So absolutely do not try to solve every problem you can think of.
Only solve the problems you really have to, that are on the table,
and begin by writing a test for them.
Because otherwise you might not even have a concrete idea for the
problem, and you’re just going to end up adding complexity and condi‐
tionals and what have you into your code, and it’ll just become a mess,
a complete mess.

71
THROWAWAY
PROTOTYPES
Throwaway prototypes

Ambitious work in software development requires prototypes that get


thrown away.
That’s just a hard fact.
If your employer doesn’t allow for throwaway prototypes, you have
the obligation to talk them out of ambitious projects.
The problem here is the whole ambitious thing. Obviously, for most
projects, you can actually do prototypes that have elements of it you
can reuse in the final project. You can do experiments that are too
small to even be called prototype.
But if you’re trying to do something ambitious, something the or‐
ganization has never done before, that it hasn’t shipped before: a new
application, a new thing, a new system, you can’t just do it.
The act of learning how to do something ambitious is iterative.
But the code that comes from the earlier experiments, doesn’t re‐
flect your learning. It doesn’t reflect the thing that you learned about
your goal, about the task that’s at hand.
It tends to reflect what you knew beforehand.
It’s a before state.
Trying to use that in the actual project and try to evolve a prototype
for an ambitious project into the ambitious project itself is tying your‐
self at the ankle to your earlier self who did not know what they were
doing.
You are basically chaining yourself to your past ignorance.

74
Yellow

You need the ability to throw away that code, that code that was
done as an exploratory effort, as a potentially misguided experiment.
Parts of it told you that this is not something you should have done.
Other parts of it told you that there are better ways to do this. That
might have worked for the prototype, but there are better ways to do
it. And you see that now.
You need the freedom and the ability to be able to throw away pro‐
totypes. To do work that results in code that gets discarded.
If your team and your organization is to be able to ship ambitious
projects and ambitious products, you need the right to dispose of code.
If you don’t have that, if you’re working for an organization that
just does not let you throw away prototypes, and it demands that
everything you work on has to be towards software that ships, if they
don’t give you the space to do that learning, then you have to, if you
want to be able to do a good job or do a job, one that does not result in
software that’s buggy and crashes and collapses over time, you have to
talk them out of it.
You have to talk them out of their ambitions.
Or convince them to let you discard prototypes.
Either way, if you’re asked to do an ambitious project without the
ability to just throw away work, because it’s the learning that matters,
then you’ve been put in an impossible position.
You have been put in a position where you are not able to do your
job. That’s untenable. That’s not something any of us should accept.
We put up with a lot in software development. We put up with so
much nonsense. We put up with expectations that are completely dis‐
connected from reality. We put up with scenarios that are just wildly,
wildly unlikely to ever be possible. We are given budgets we know are
just fabrications.
But we have to draw the line somewhere. And we need to try at least
somewhere to draw the line and say, what you’re asking me to is just not
possible. It’s not realistic. And try to walk them back.
Or, you know, try to convince them to let you prototype. Let you do
experiments. Because that’s actually how you make ambitious things
happen. The return on investment on ambitious things tends to be

75
Throwaway prototypes

higher than just always going with the most conservative risk-free ap‐
proach.
If you really want to bet, make big bets and have big rewards, you
need ambition. And for that you need to be able to prototype.
That’s just a hard requirement.

76
DON’T BE A
CORRECTNESS BULLY
Don’t be a correctness bully

Don’t be a correctness bully.


We all know the type that is just, “that’s not the way you do that”.
“You’re doing it wrong”.
“You need to do this a different way.”
You have the people who correct people’s grammar, endlessly.
Even if the original might not have been technically wrong, they
find flaws with it anyway, because everything is flawed.
You can always find flaws, but there’s a difference between knowing
what is correct and incorrect and being able to communicate that to
people who have asked you for that feedback.
Then you have the people who are correctness bullies and use their
knowledge of correctness or incorrectness to bully or manipulate
their co-workers. Software developers more often than not fall into
the bullying category. They – which is ironic considering that how
many software developers experienced bullying themselves – tend to
be absolutely horrendous towards newcomers, towards those who are
just starting out towards those who are unfamiliar with the industry.
They keep bullying people with correctness, rather than trying to
reinforce what people – the parts that people do well. Positive rein‐
forcement is the only thing that works.
It doesn’t matter whether you’re teaching, or training an animal,
or communicating, you can’t talk people out of their misconceptions,
their dislikes, or bad habits.

78
Yellow

The only viable solution in most training, in most communication,


is positive reinforcement – is reinforcing the things that are done
right.
Because then they will do those things again, and they will associ‐
ate your feedback with something positive, with a positive emotion
and with an improvement in their work.
If you bully them on what they do incorrectly, they will associate
you with something negative – with feeling bad. They won’t do the in‐
correct thing less.
Because that’s not how the human mind works.
We don’t work along the lines of negative reinforcement. We work
on the lines of positive reinforcement. We seek out things are benefi‐
cial, trigger positive emotions, and feel constructive. So don’t be a cor‐
rectness bully.
Try to focus on positive reinforcement and don’t try to talk some‐
body out of hating something.
This goes for every aspect of software. You can’t talk somebody out
of hating CSS. You can’t talk somebody out of hating JavaScript or
fearing HTML. But you can reinforce the positive. Give the behaviour
you want and think is desirable, positive reinforcement. When some‐
body tries their hand at CSS who otherwise avoids it, you focus what
they have done well and point out how to do it better.
If somebody who is usually just wraps everything in HTML in a div,
then attaches JavaScript and calls it a button, you should not focus on
how bad of an idea this is, the fact that they made something that’s
horrendously inaccessible and is going to ruin some end-users life.
You focus on what they did well, the structure, the fact that the overall
widget behaved, and then add:
“If you switch that to a HTML button element you get a lot of other
stuff for free. It makes your work automatically better. You can im‐
prove what you’ve already done just by renaming the element. Now it
gets focusing features and keyboard activation for free.”
You’ve given them positive reinforcement. You’ve told them how to
take what they already know and do better. You haven’t told them that
what they did is bad and that they’re bad people for doing it that way.

79
Don’t be a correctness bully

So, positive reinforcement.


It’s the only way to genuinely change behaviour, and it’s pretty
much the only way to train or teach anybody, even yourself.
Being negative about your own work has the same effect.
Focusing on positive reinforcement for yourself is just as important
as it is with people around you.
Try and see and focus on what you can improve with what you have
done instead of focusing on thinking of it as a flawed thing.
Don’t think that doing it was a mistake.
Make it better.
Don’t think of your work as mistakes.
Think of them as things that you can do better.

80
WORSE IS BETTER,
BUT IT’S ALSO HOW
WE GOT INTO THIS
MESS
Worse is better, but it’s also how we got into this mess

Worse really is better.


But it’s also how we got into this mess.
If you aren’t familiar with the term worse is better, it comes from
the early days of the software industry.
Most fields, especially the ones that have some sort of creative di‐
mension to it – of which I consider software development to be one –
tend to have two opposing theoretical frameworks that are in constant
conflict.
If you look through literary history, in literature and drama, this
dynamic gets expressed as romanticism versus classicism.
Romanticism is all about the larger context of the work, the emo‐
tions, the people, how it plays out.
The author of a romantic work matters almost as much as the work
itself. Byron, Shelley.
Classicism focuses on meaning that’s found in the work itself.
The author and the environment and the context does not matter.
It’s the work itself that matters. The text is what matters.
You can see why these two approaches are in opposition. One
claims that the work primarily gets its meaning from context. The oth‐
er claims that the work primarily gets its meaning from itself and its
structure. It should also be obvious why adherence to these two move‐
ments tend to always be in a spiral of evolution, where they grow and
evolve their ideas in constant argument with the adversary, who is
also always evolving their ideas, and they never come together.

82
Yellow

Actual practice in literature and writing and drama tends to be a


mixture of the both.
The author and context are both always going to matter to some de‐
gree. We exist in a society, and we can’t rid ourselves from it.
But meaning is also in the work itself.
Once we have a base level of understanding of language and text
and how texts work, each text will carry a meaning of its own.
Its structure will tell you something on its own. You might not see
all of it, but it’s still there.
So the reality is always somewhere in between.
Software development has two similar opposing ideas.
You have the ideological kin to the literary classicists who focus on
the correctness of the work and writing software that using ap‐
proaches that are structurally correct.
Back in the day, this wing of software development bet on LISP.
They had bespoke machines for running LISP programming code.
They tended to be obsessed with proven validation of correctness
and being able to build software incrementally and be sure that all of it
works properly and was stable through mathematical proofs.
I’m caricaturing the position a bit, but that’s a gist.
The software should be able to prove to some degree its own cor‐
rectness.
The idea was that the only way to make defect-free software was to
make it impossible for it to have defects through language and plat‐
form design.
The other side – the ideological adversary – of the code classicists
would be the Unix, C and BSD side of the industry, which basically
said, what if we just get things done and build things out of simple con‐
cepts to begin with and then improve it from there?
It’s going to have bugs, but we’re going to be able to fix it afterwards,
right?
That was basically how the LISP crowd caricatured the success of
Unix. They called it the worse is better approach.
The worse is better idea was that by layering on these relatively
crude languages and systems, you would end up with more correct

83
Worse is better, but it’s also how we got into this mess

software – as in more software that’s roughly correct – than with the


alternative approach. The classicist approach, conversely, gave you
software that was more correct, but less of it and slower overall be‐
cause the work went at a much lower pace.
The worse is better approach has won out over the past 40 years. We
just hammer things together, and we try and fix things afterwards.
Tthat’s pretty much the only way for us to be realistically able to
ship software.
If we wait until we can prove mathematically, conclusively, that a
piece of software has no defects, we’re going to be waiting forever.
It’ll never ship. We’ve built an entire industry on the concept that
we’re going to try and fix things later.
The problem is we’ve discovered that we can’t.
These errors and mistakes and flaws are baked into the concept, and
now we’ve built layers and layers and layers on top.
We have this tension where the only way to ship anything realistic‐
ally that works for people is to do it imperfectly, and those imperfec‐
tions collect and build up over time.
Now, more often than not, the software industry is dealing with ac‐
cumulated defects in some capacity.
There are security flaws in everything. There are user interface
flaws in everything. Everything is hard to use.
Everything accumulates. Things have become too complex for quite
a lot of people.
So we live with a compromise, and there’s nothing really we can do.
We can minimize the imperfections we ship because we can do unit
testing.
We do a test-driven development. We can use type checking when
that’s appropriate.
But this compromise is baked into our industry. Worse is better.
We ship imperfections because, on the whole, it’s better.
The improvement, on the whole, has a bigger impact than the de‐
fects we’re shipping with it.

84
Yellow

But the defects are still there, and they’re still accumulating, and
we’ve coasted for the past decades on the fact that the improvements
are collecting faster than the defects.
Occasionally, for some software systems, you actually get the op‐
portunity to stop and pause and try and fix some of the defects.
But you can never get rid of them all because “let defects ship” is
baked into how the entire industry works.
We’re working in a compromise system, and we need to be aware of
that because otherwise the trash we ship gets even more trashy.
There’s nothing we can do to truly fix it.
Not in this lifetime.
We’d have to invent an alternate timeline. Where we made different
choices 50 years ago and decided to prioritize correctness. Where the
software we’re using is much less capable than the software we have
today, but has fewer flaws, is easier to use, and doesn’t have the near-
singularity, black-hole-singularity levels of defects that our current
system has.
But that world doesn’t exist.
We have to live in this one.
Even if it’s disappointing, occasionally.
When you get up in the morning and see yet another bug report.
It’s the job.

85
YELLOW
Yellow

At the start of this project, I talked about the title, Yellow, and its in‐
spiration, Derek Jarman’s Blue, how that was born out of his illness.
I spoke about the fact that his motivation, his drive for his film was
much grimmer than for my simple project.
But there’s still a side to this that’s less uplifting.
Over the past year I’ve been pushing out books, projects, and art‐
icles. I released the book Out of The Software Crisis in November a year
ago. So, just over a year has passed since I began this push.
After that, I released another ebook. I’ve done more talks in the
past year than I’ve done in recent years. I’ve been pushing, writing
more, publishing more, and much of it comes from fear.
The same fear I said earlier on should only be thought of as a signal
and should not be something you let control you.
But I’ve been yellow. I’ve been letting this fear control me.
Over a year ago this summer, last year, I managed to catch COVID
for the first time.
I’ve been good at avoiding it, masking and everything, but my dad
caught it during a hospital appointment, and then I caught it from
him.
The illness itself was fine. It was just a flu-like thing. The problems
came afterwards.
For six weeks, my brain just wasn’t working. My memory was aw‐
ful. I had no way of focusing. My mind wasn’t my own any more.

88
Yellow

It meant I couldn’t work for six weeks. It cost me both time and
money. It affected my relationship with the people who’d hired me as a
consultant. It probably cost me that project in the long term.
But it frightened me in other ways as well.
About halfway through I could feel myself getting better. I was able
to start working again six weeks in. But it took more than six months
for me to sort of get back to the level I used to in terms of being able to
think and remember and structure my own thoughts. I’m still not
100%, even a year later.
This might sound surprising. That means that I wrote my first book
in a deep haze of COVID fog, where I frantically wrote what I could in
the between moments where I felt lucid and otherwise tried to focus
on working the easier tasks of editing and typesetting. Not that I want
to downplay the magnificent work that proper typographers do. I felt
that that was easier for me to focus on in that context.
I was driven by fear because I’ve seen this kind of change happen
well before COVID. One of the running ailments you notice if you look
through my family tree is vascular dementia.
Now, that goes hand in hand with lifestyle. There are people in my
family tree who drink, who don’t exercise, who eat loads of fatty
foods.
Many of them suffered from vascular dementia, sometimes from a
frighteningly early age.
So just by having the correct lifestyle and exercising, I had figured I
should be fine. I mean, it reduces the odds enough that I should be
fine.
But, you know, the possibility is always there in your mind, at the
back of your mind.
And that meant I have a certain awareness of what dementia looks
like.
And COVID felt like that.
It really felt like the same sort of chipping away at the ability to re‐
call, at the ability to hold focused thoughts and structure arguments,
felt like the same kind of deterioration that I saw in my granddad.

89
Yellow

So I’ve been pretty terrified for the past, what have you, year or so,
driven by fear in that – not really of the dementia, but just of this
awareness that the mind is a fragile thing.
It can be taken away at a moment’s notice.
But I’ve also been driven by the fact that low odds – having lowered
odds through better exercise and a more constructive lifestyle – is still
not zero.
This is always going to be a possibility going forward.
I got a preview of a possible future.
So I’m yellow. I’m full of fear.
It drove me to try and write a book to capture my opinions and my
thoughts on software development.
It’s what drove me to try and give people warning about the busi‐
ness risks that “AI” or generative “AI” had in the long term.
It’s what drove me to the research projects I’ve been trying to do
and trying to pull together this year.
And it’s what drove this project.
It’s looking at the way Jarman, the dying director, solved his prob‐
lem, which was, you know, more imminent, much more imminent
than hopefully something that might happen to me in a few decades.
Fingers crossed.
But his way of just using a blue screen with audio – that’s a way of
cutting corners, while still being expressive about it.
So this project was born, or reborn, because I’ve been actually
working on this for a while.
The first draft of these principles were written last spring, several
months ago.
I’ve been working on them since. Trying to sort of whittle them
down, hone them, and pick and choose.
But I always had this worry about how – how can I get this out in a
way that’s accessible but also quick?
Because, as I said, I’m frightened.
I’m worried that I want to maximize how… I want to use the time
that I have as well as I can.
Like I said, I don’t expect to be struck down anytime soon.

90
Yellow

I genuinely hope it won’t happen or that if it happens it’ll be in my


80s or something.
But I don’t want to be in a position where – if I’m placed in that pos‐
ition, I don’t want to be in a position of regret.
Of being filled with an undercurrent of anger and bitterness about
what was left unsaid.
About not managing to convey or help or do what I wanted to do.
I’d like to think that if I play out, you know, my career correctly,
that if it does happen, instead of being lost in indistinct anger that
poisons the people around me, that instead I’ll have some peace, and
I’m caught in an eternal moment. A present. Or a moment from the
past.
I’d like to think that. I hope so. But in the meantime, this was
Yellow.
Some principles for software development.
Some of them useful.
Some of them simplistic aphorisms.
Some of it oddly personal.
But hopefully it’ll be more useful than not.
Hopefully, this’ll help somebody out there get things done in a hu‐
mane manner.
This has been Baldur Bjarnason speaking from Hveragerði, looking
out at a snowstorm.

91

You might also like