The Elements of Style
Don't think about elephants
Kevlin Henney
What a horse is, is evident to everyone.
Definition of a horse once given in an encyclopaedia
They followed the dog silently for a while.
Then LaVerne asked John, "What kind of dog is that?"
John thought about it and said, "That's a good dog."
Robert M Pirsig
Style is the manner in which you express yourself or perform your work. It covers
principally form and appearance; it is as relevant to programming as it is to
composition arguably programming is composition. Programming is many things
to many people: to some it is a corner of mathematics, and to others it is the
high frontier where there are and should be no rules. The mind set of most
software engineers exists somewhere between the belief that the code required
for SDI (Strategic Defense Initiative) is formally verifiable and the belief
that any formalisation is an attempt to restrict personal freedom and creativity.
Good style is ultimately subjective; objectively, it is a set of informal
formalisms. All programmers acquire certain rules of thumb with experience: some
are related to aesthetics and others to the prevention, rather than the cure, of
bugs. I group a number of these under the label of style. Good style, whatever
it is, should be a requirement of quality code. It clearly relates to how we
express a solution; how we illustrate it and emphasise certain features to others.
So what is it and how does one learn and achieve good style? In a bid to
encourage people to write better code certain guidelines are often handed out.
Many of these have been reduced to aphorisms with folkloric status. I will take
three of the most common:
- Choose meaningful variable names.
- Comment your code.
- Don't use gotos.
These are as common as they are useless. They offer no method and are so widely
subject to interpretation that almost any solution satisfies:
- I knew of someone, working in a commercial environment, whose favourite
variable name was A. He started naming variables from the beginning of
the alphabet and worked forward. The meaning of A was "the first
variable I thought I needed when I started writing this".
- A colleague once worked with a trainee who asked his project manager how much
commenting his Pascal program required. When told that it should be enough to make
the program clear to anyone reading it, he went away and duly returned with
commented code that taught the reader Pascal from scratch.
- What happens if, somewhere down the line, along with picking up advice about
gotos you also pick up strange ideas about nesting and elses?
One coder I knew regarded all of these as a problem. This contradictory style of
coding, worthy of an electric monk, was peculiar and unmaintainable to say the
least: instead of elses you have to negate the condition checked in the
previous if; instead of nesting you have to place certain loops or
conditionals after the block they should be inside, adding the condition of this
previous condition to their own. The code mushroomed towards the end of each
module, and in places the memetic tension opened up a logic fault line that only
a goto could bridge.
Dealing with each of these points in turn, it is the first maxim that started me
down this track. I used it recently in a letter against Hungarian notation. Some
time after writing it I realised I had written a content-free sentence:
proponents of this cipher argue that because they embed low-level type
information in names their variable names do have meaning; opponents argue that
meaning says something about how a variable is used and not its incidental
low-level type, i.e. it relates to conceptual rather than implementational type.
Some qualification of the word 'meaningful' is required.
There is no need to write comments on drool-proof paper. Assume some
intelligence in the reader, such as fluency in the language of choice and
familiarity with its idioms. Stroustrup nicely sums up basic requirements for
commenting [The C++ Programming Language, 2nd edition]:
Comments can be misused in ways that seriously affect the readability of a
program. The compiler does not understand the contents of a comment, so it has
no way of ensuring that a comment
- is meaningful,
- describes the program, and
- is up to date.
Most programs contain comments that are incomprehensible, ambiguous, and just
plain wrong. Bad comments can be worse than no comments. If something can be
stated in the language itself, it should be, and not just mentioned in a comment.
There are very good reasons that gotos are particularly loathsome in
high-level languages, but if these reasons are not understood any number of
insidious memes may take over your coding style. The absence of gotos
is a consequence of structured programming, and not the cause. This is where the
elephants fit in. Without a reason, the advice given in the title is quite
pointless. It is also contradictory. Actively not thinking about elephants will
cause you to think about them. A significant amount of code seems to take this
goto folk saying at face value: it appears to have been conceived in
terms of gotos, but then had them all ripped out. The resulting logic and flow
of control simply illustrate that unstructured programs do not require gotos.
There are many valid interpretations of open questions. This is true both in
formal specification and natural language. The trick to giving good answers is
getting the right question. One would do well not to ignore these maxims.
Reflection is needed: they are excellent pieces of advice if given in full.
What defines good style should be backed up with reason. Good style itself should
serve a purpose, that of clear and unambiguous communication of ideas. Style is
about the expression of meaning; it is about delivery. It is also best
illustrated in context. Before I get accused of delivering only the maxim
without the reason, I will be returning to these areas and others in future
articles.
© Kevlin Henney
First published in CVu 6(6), September 1994
Converted to HTML, February 2001