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:

  1. Choose meaningful variable names.
  2. Comment your code.
  3. 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:
  1. 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".
  2. 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.
  3. 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]:

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