[Note: this post represents the notes made for my talk at iOS Dev UK 2014. As far as I’m aware, the talk isn’t available on the tubes.]
The Principled Programmer
The first thing to be aware of is that this post is not about my
principles. It’s sort-of about your principles, in a way.
On dichotomies
Let’s look at two games. You may not have heard of Chaturanga (unless
you practice yoga, but I’m talking about a different Chaturanga), but
it’s the ancient game that eventually evolved into Chess.
You may not have heard of Nard either, but it’s a very different game
that grew up into Backgammon. There’s a creation myth surrounding
these two games, that says they were invented at the same time. Some
leader thousands of years ago wanted two games; one a game of skill
and the other a game of chance.
The thing is, you can lose at chess by chance: if you happen to be
having an off day and miss a key move that you’d often
make. Similarly, you can lose at backgammon through lack of skill: by
choosing to move the wrong pieces.
We were presented with two options: skill (chaturanga) and not-skill
(nard). However, the games do not actually represent pure states of
the two concepts; they’re more like a quantum system where the
real-world states can be superpositions of the mathematically “pure”
states.
All of this means that we can’t ignore states in-between the two
poles. Such ignorance has a name in the world of critical analysis:
the fallacy of the excluded
middle.
That is not the situation we have in bivalent logic, including the
mathematical Boolean formulation frequently used to model what’s going
on in computers. This has the law of the excluded
middle, which
says that a proposition must either be true or false.
In this case, the fact is that the two propositions (you are playing a
game of skill, or you are playing a game of chance) do not exactly
match the two real possibilities (you are playing chaturanga, or you
are playing nard). There’s a continuum possibility (you are using some
skill and some chance), but a false dichotomy is proposed by the
presentation in terms of the games.
On rules
The existence of a rule allows us to form a bivalent predicate: your
action is consistent with the rule. That statement can either be true
or false, and the middle is excluded.
This means we have the possibility for the same confusion that we had
with the games: compliance with the rule may be bivalent, but what’s
going on in reality is more complicated. We might accidentally exclude
the middle when it actually contains something useful. Obviously that
useful thing would not be in compliance with the rule. So you can
think about a rule like this: a statement is a rule when you can
imagine contraventions of the statement that are of no different value
than observances of the statement. Style guides are like this: you can
imagine a position that contravenes the rules of your style guide
that is of no lesser or greater value: following another style
guide.
Of course, the value of a style guide comes not from the choice of
style, but from the consistency derived from always adhering to the
rule. It doesn’t matter whether you drive on the left or the right of
the road, as long as everybody chooses the same side.
One famous collection of rules in software
engineering is Extreme Programming. Kent Beck described hearing or
reading about various things that were supposed to be good ideas in
programming, so he turned them up to eleven to see what would
happen. Here are some of the rules.
-
User stories are written. It’s easy to imagine (or recall)
situations in which we write software without writing user stories:
perhaps where we have formal specifications, or tacit understandings
of the requirements. So that’s definitely a rule. -
All production code is pair programmed. The converse – not all
production code is pair programmed – poses no problem. We can imagine that the two conditions are different, and that we might want to choose one over another.
Rules serve two useful functions, of which I shall introduce one
now. They’re great for beginners, who can use them to build a scaffold
in which to place their small-scale, disjoint bits of knowledge. Those
bits of knowledge do not yet support each other, but they do not need
to as the rules tell us what we need to apply in each situation.
The software engineering platypus
Having realised that our rules are only letting us see small pieces of
the picture, we try to scale them up to cover wider
situations. There’s not really any problem with doing that. But we can
get into trouble if we take it too far, because we can come up with
rules that are impossible to violate.
A platitude, then, is a statement so broad that its converse cannot be
contemplated, or is absurd. Where a rule can be violated without
hardship, a platitude cannot be violated at all – or at least not
sensibly.
The problem with platitudes is that because we cannot violate them,
they can excuse any practice. “I write clean code”: OK, but I don’t
believe I know anybody who deliberately writes dirty code. “This
decision was pragmatic”: does that mean any other option would be
dogmatic? But isn’t “always be pragmatic” itself dogma?
Platitudes can easily sweep through a community because it’s
impossible to argue against them. So we have the software
craftsmanship manifesto, which values:
-
A Community of Professionals. As any interaction
between people who get paid comes under this banner, it’s hard to see
what novelty is supplied here. -
Well-Crafted Software. Volunteers please for making shitty
software.
The Principled Programmer.
There must be some happy medium, some realm in which the statements we
make are wider in scope, and thus more complex, than rules, but not so
broad that they become meaningless platitudes that justify whatever
we’re doing but fail to guide us to what we should be doing.
I define this as the domain of the principle, and identify a principle
thus: a statement which can be violated, where the possibilities of
violation give us pause for thought and make us wonder about what it
is we value. To contrast this with the statements presented earlier:
-
violate a rule: meh, that’s OK, the other options are just as good.
-
violate a platitude: no, that’s impossible, or ludicrous.
-
violate a principle: ooh, that’s interesting.
Coming up with good principles is hard. The principles behind the
agile manifesto contain some legitimate principles:
-
Our highest priority is to satisfy the customer through early and
continuous delivery of valuable software. Interesting. I can imagine
that being one of many priorities of which others might be higher:
growing the customer base, improving software quality, supporting what
they’re using now and deferring delivery of new software until it’s
needed. I’ll have to think about that. -
Working software is the primary measure of
progress. Interesting. This seems to suggest that paying off technical
debt – exchanging one amount of working software for another amount of
working software over a period of time – is not progress. I’ll have to
think about that.
But then it also contains rules:
-
Deliver working software frequently, from a couple of weeks to a
couple of months, with a preference to the shorter timescale. We ship
a couple of times a day, and I don’t feel that’s worse. -
Business people and
developers must work together daily throughout the project. Is there
anything wrong with every other day?
And platitudes:
-
Build projects around motivated individuals. Give them the
environment and support they need, and trust them to get the job
done. I cannot imagine a situation where I would hire people who do
not want to do the work. -
Continuous attention to technical excellence and good
design enhances agility. This is tautological, as technical excellence
and good design can be defined as those things that enable our goals
and processes.
Why is it hard? I believe it’s because it’s highly personal, because
what you’re willing to think about and likely to get benefit from
thinking about depends on your own experiences and interests. Indeed
I’m not sure whether I want to define the principle as I have done
above, or whether it’s the questions you ask while thinking about
the validity of those things that are really your principles.
## Nice principles. Now go and turn them into
rules.
The thing about thinking is that I don’t want to do it when I don’t
need to. My currency is thought, so if I’m still thinking next year
about the things I was considering this year, I’m doing it wrong.
Principles are great for the things that need to challenge
the way we work now. But they should be short-lived. Remember the
beginner use of rules was only one of two important contexts? The
other context is in freeing up cognitive space for people who
previously had principles, and now want to move on to have new
principles. In short-circuiting the complex considerations you
previously had, mentally automating them to prepare yourself for
higher-level considerations.
Notice that this means that it’s a rule in isolation that doesn’t cause us any problems to violate. It may be that the rule was derived from a principle, so some thought went into its construction. Without that information, all we can see is that there are two possibilities and we’re being told that one of them is acceptable.
The challenge that remains is in communication, because it doesn’t
help for the context of a rule to be misidentified. If you’re a
beginner, and you describe your beginner rule and someone takes it as
an expert rule, they might end up talking about perspectives that
you’re not expecting. Also if you’re an expert and your expert rule is
perceived as a beginner rule, you might end up having to discuss
issues you’ve already considered and resolved.
So by all means, identify your principles. Then leave them behind and
discover new ones.
I know the game thing wasn’t the point of your post and was just a jumping off point, but I find the luck vs skill thing in games very interesting. Richard Garfield (he of Magic: The Gathering and much more) has argued very convincingly that luck and skill are not in opposition, but are orthogonal. So you can have:
High skill, low luck, like chess.
High skill, high luck, like poker.
Low skill, low luck, like tic-tac-toe.
Low skill, high luck, like snakes & ladders.