The Programming Aphorisms of Strunk and White
Monday, October 13, 2008   

If I could take ten software development books to a desert island, The Elements of Style by William Strunk and E.B. White would be one of them. 

The Elements of Style

Of course, "Strunk and White," as the book is commonly called, has nothing to do with software (it was written in 1935) and everything to do with writing: grammar, composition, and style for users of the English language. But in its 100 short pages this book has more to say about the craft of software than many books you'll find in the "Computing" section of your local bookstore. All you have to do is replace a few key words throughout the text and presto! Pearls of software development wisdom, delivered in near-perfect English.

Like this one, which discusses the importance of proper software design.

2.12. Choose a suitable design and hold to it.

A basic structural design underlies every kind of writing programming. Writers Programmers will in part follow this design, in part deviate from it, according to their skills, their needs, and the unexpected events that accompany the act of composition. Writing Programming, to be effective, must follow closely the thoughts of the writer programmer, but not necessarily in the order in which those thoughts occur. This calls for a scheme of procedure....in most cases, planning must be a deliberate prelude to writing programming. The first principle of composition software development, therefore, is to foresee or determine the shape of what is to come and pursue that shape.

The last sentence is telling: the first principle of composition is to foresee or determine the shape of what is to come and pursue that shape. This is really what we're doing when we build software. All of the rigorous development schedules, iterations, use cases, only serve to fill in the blank software canvas we're presented with, in a way that (hopefully) creates working software in a timely fashion without going over budget. Of course, we can't go with just any design for our applications; the design must suit the problem at hand.

5.3. Work from a suitable design.

Before beginning to compose develop something, gauge the nature and extent of the enterprise and work from a suitable design. Design informs even the simplest structure, whether of brick and steel or of prose. You raise a pup tent from one sort of vision, a cathedral from another. This does not mean that you must sit with a blueprint always in front of you, merely that you had best anticipate what you are getting into. To compose a laundry list, you can work directly from the pile of soiled garments, ticking them off one by one. But to write a biography, you will need at least a rough scheme; you cannot plunge in blindly and start ticking off after the fact about your subject, less you miss the forest for the trees and there be no end to your labors.

Some programmers take a very simple problem and needlessly complicate it with design overkill. Other programmers take a very complex problem and underestimate it; they just start coding. Both behaviors are equally deadly. There's an appropriate design effort for every project, based on its intended functionality, and the difficulty or complexity of realizing that functionality. You don't want to do too little design; equally, you don't want to do too much. Instead, like Goldilocks, you want to choose the bowl of design porridge which is just right.

5.21. Prefer the standard to the offbeat

Young writers Inexperienced programmers will be drawn at every turn toward eccentricities in language. They will hear the beat of new vocabularies abstractions, the exciting rhythms of special segments of their society industry, each speaking a language of its own. All of us come under the spell of these unsettling drums; the problem for beginners is to listen to them, learn the words, feel the vibrations, and not be carried away.

This is a rule we Microsoft ecosystem programmers violate all the time, because the Microsoft technology avalanche amounts to a sort of de facto standard. So when Microsoft comes out with a new library, a new MFC or WPF, and says "use this!" we listen. The result is standard-but-not-quite-standard code which fares well in a Microsoft habitat (for five or ten years) but which creates a lot of work when we want to port or expose these same systems to other platforms. The same sort of problem affects, to a lesser degree, the sprawling Linux ecosystem. And it's likely that both Microsoft and non-Microsoft approaches could be cleaned up by applying Occam's Razor liberally:

2.17. Omit needless words code

Vigorous programming is concise. A function should contain no unnecessary statements, a statement no unnecessary expressions, for the same reason that a drawing should have no unnecessary lines and a machine no unnecessary parts. This requires not that the programmer make all functions short, or avoid all detail and treat subjects only in outline, but that every line of code tell.

Don't unnecessarily multiply things! Don't create arbitrary divisions between things! Damnit man! Things like: lines of code. Objects. Methods. Enumerations. Components. If you've ever looked at production source code for a major application or operating system, your initial reaction is likely to be one of shock: what the $!@$ is all this crap? This is a good reaction, not a bad one. Excess code turns software maintenance into a nightmare, because it exterminates clarity, and increases the amount of brain cycles required to achieve understanding of the code. Or as Strunk and White would say:

5.16. Be clear.

Clarity is not the prize in writing programming, nor is it always the principle mark of good style. There are occasions when obscurity serves a literary programmer yearning, if not a programming purpose, and there are writers programmers whose mien is more overcast than clear. But since writing programming is communication, clarity can only be a virtue.

Of course, clarity in software is arguably more important than clarity in writing, because the clarity of production code affects the dollar cost of producing and maintaining a piece of software. In other words, lack of clarity costs companies millions upon millions of dollars each and every year. And even though it's important to:

5.2. Write Program in a way that comes naturally

Program in a way that comes easily and naturally to you, using words and phrases APIs and statements that come readily to hand. But do not assume that because you have acted naturally your product is without flaw.

It's even more important that we:

5.9. Do not affect a breezy manner

The volume of writing source code is enormous, these days, and much of it has a sort of windiness about it, almost as though the author programmer were in a state of euphoria. "Spontaneous me," sang Whitman, and, in his innocence, let loose the hordes of uninspired scribblers script kiddies who would one day confuse spontaneity with genius.

Give each line of code its due. If a particular function calls for the use of an unfamiliar API, learn the API rather than going the quick and dirty route. In Windows codebases you'll often see someone spawning a process using LoadModule even though it's deprecated. They do this because the recommended function, CreateProcess, takes a small army of parameters (ten, to be precise) whereas LoadModule takes two.

BOOL WINAPI CreateProcess(
  __in_opt     LPCTSTR lpApplicationName,
  __inout_opt  LPTSTR lpCommandLine,
  __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in         BOOL bInheritHandles,
  __in         DWORD dwCreationFlags,
  __in_opt     LPVOID lpEnvironment,
  __in_opt     LPCTSTR lpCurrentDirectory,
  __in         LPSTARTUPINFO lpStartupInfo,
  __out        LPPROCESS_INFORMATION lpProcessInformation
)

It's always cheaper to code things correctly the first time, than it is to code them incorrectly and fix them later. On the other hand, code, like prose, is almost never perfect (or even adequate) in its first incarnation. That's why it's important to:

5.5. Revise Refactor and rewrite

Revising is part of writing. Refactoring is part of coding. Few writers programmers are so expert that they can produce what they are after on the first try. Quite often you will discover, on examining the completed work system, that there are serious flaws in the arrangement of the material, calling for transpositions.

If Strunk and White were alive today, they'd probably be big fans of Agile and other iterative, incremental development processes which a) emphasize simplicity and b) allow ample opportunity for stepwise improvement. Of course, we don't need Agile (or Strunk and White) to tell us that it's a good idea to: 

2.17. Omit needless words code

Vigorous writing programming is concise. A sentence function should contain no unnecessary words code, a paragraph block of code no unnecessary sentences statements, for the same reason that a drawing should have no unnecessary lines and a machine no unnecessary parts. This requires not that the writer programmer make all functions short, or avoid all detail and treat subjects only in outline, but that every word line of code tell.

If there were ever such thing as a universal design criterion, simplicity would be it. And one of the main ways we achieve simplicity is by cutting out the stuff we don't need. In the art world we have movements (such as the Baroque) which revel in complexity, and in writing we have expansive authors like Cormac McCarthy, but generally speaking, the simpler the writing/code/system/work of art, the better. Better because more intelligible; easier to maintain; and structurally more sound.

Young writers programmers often suppose that style is a garnish for the meat of prose code, a sauce by which a dull dish is made palatable. Style has no such separate entity; it is nondetachable, unfilterable. The beginner should approach style warily, realizing that it is an expression of self, and should turn resolutely from all devices that are popularly believed to indicate style -- all mannerisms, tricks, adornments. The approach to style is by way of plainness, simplicity, orderliness, sincerity.

Speaking of structure:

2.19. Write Express coordinate ideas in similar form

This principle, that of parallel construction, requires that expressions similar in content and function be outwardly similar. The likeness of form enables the reader to recognize more readily the likeness of content and function.

Object-oriented programming makes the uniform expression of coordinate ideas relatively easy, using basic techniques:

  • Inheritance
  • Generics / Templates
  • Interfaces

There are others, but every programmer is familiar with a typical class hierarchy in which common functionality is pushed up to the superclasses, and specific functionality falls downward towards the leaf classes, and maybe there are some templatized collection classes, along with a few interfaces. We can ply our specific domain against these constructs elegantly when the nouns of that domain are coordinate:

  • Animal
  • Mammal
  • Dog
  • Cat
  • Moose

Of course, too much object-orientation, or "object orientation for object orientation's sake", can be a Very Bad Thing. If we asked Strunk and White they'd probably say:

5.6. Do not overwrite over-program

Rich, ornate prose code is hard to digest, generally unwholesome, and sometimes nauseating.

Ask yourself, when you're trying to copy some text from location A to location B, whether it's better to allocate a chain of distributed COM objects, consult the Registry, set up an eventing hierarchy and spawn a couple worker threads, or just use a plain vanilla string copy.

Another good one has to do with commenting code:

5.11. Do not explain too much.

It is seldom advisable to tell all. Be sparing, for instance, in the use of adverbs code comments...Let the conversation code itself disclose the speaker's manner or condition coder's intention.

Although each programmer has his own commenting philosophy, experience shows that the amount of code comments usually varies inversely with the programmer's experience level; not because more experienced programmers are more lazy, but because their code is clearer in and of itself. Good code is self-documenting.

Last but not least, one of my favorite elements of style, and what to me is the fundamental rule of surviving a multiple-person development effort:

5.1 Place yourself in the background.

Write Program in a way that draws the reader's attention to the sense and substance of the writing code, rather than to the mood and temper of the author programmer. If the writing code is solid and good, the mood and temper of the writer programmer will eventually be revealed, and not at the expense of the work.

There's little to no room for ego in team-oriented production code. Pride of craftsmanship, yes. Petulant emotional investment, no. Subtract yourself from your code and watch your code improve. I may or may not be a talented programmer; you may or may not be; but if we're capable of using every available resource, including the minds of those around us, and leveraging rather than resenting criticism levelled against "our" code, everything improves across the board.

Hopefully.

Anyway, the next time you have a few spare minutes, grab that old copy of Strunk and White's Elements of Style, and start applying some of your lifelong knowledge of the written word to programmable code. They're two very different things, but beneath the differences, at the level of conceptualization, and in the serial process of actually cranking out individual lines of code, very much the same.


Posted by James Devlin   26 comment(s)

SEARCH

COMMENTS

Weird but...interesting. Sort of. I mean, Strunk and White? English? Grammar? YARK. We don't need no stinkin' grammar. But as usual you put your weird little Machiavellian spin on it. Anyway, bitches: I AM FIRST. KNEEL BEFORE ZOD.

Anonymous on 10/13/2008 6:20:00 PM (85 days ago)

Get real! Strunk and White is one of the few English stylebooks which is worth a damn.

great post, J.D.

JeremyX on 10/13/2008 7:03:05 PM (85 days ago)

ZOD... lol. Blast from the past.

JeremyX on 10/13/2008 7:03:33 PM (85 days ago)

Nice to see you back. Thanks for the advice.

Terry Smith on 10/13/2008 7:35:52 PM (85 days ago)

Nice. But I've also always found that writing and programming are opposite too. For instance, in good writing they suggest you vary the length of the sentences, paragraphs, etc. and find as many different ways as possible to express your ideas. Inconsistency, it seems, makes it more enjoyable to read; nothing is worse than a long slog through a dry repetitive boring text. Good code, on the other hand, should be as dry and boring as possible; consistency is key to making it both easy to determine what the code is doing, but also in highlighting simple obvious mistakes. So, in that way, the two forms of expression are very opposite.

Paul.

Paul W. Homer on 10/13/2008 8:01:28 PM (85 days ago)

Great article - I actually had a really similar thought earlier this year and wrote a remarkably similar article. It's amazing how similar programming and writing are - and at that, how many great coders are great writers.

James Golick on 10/13/2008 11:38:41 PM (84 days ago)

I have to disagree with Paul, here. If your code is repetitive, you have missed an opportunity to abstract out the repetitive part.

Daniel Stutzbach on 10/14/2008 12:51:31 AM (84 days ago)

Very interesting insight, enjoyed that. Especially like how sentences can be taken out of Strunk and White, and applied in the context of programming just by replacing certain words. Re-phrasing wasn't even necessary! If only programmers coded as well as Strunk and White wrote, then refactoring code would be so much easier. Laughing

ehsanul on 10/14/2008 4:01:18 AM (84 days ago)

Have to disagree on comments. I comment all my stuff extensively and have done so for years. C and C++ are not the clearest languages when expressing intent. I am currently in a new job and looking at a complex C/C++ server application with >200,000 lines of code. The lack of comments is driving me crazy as I have no idea what the individual programmers are doing a lot of the time. The overall structure is clear and the design is very good, however at some stage one has to delve into detail and a few comments would be helpful. The agile mantra of 'the code is the comment' does not hold up well in my experience. Make the code short but don't stint on the comments!

tring on 10/14/2008 5:10:44 AM (84 days ago)

>I love how you repeated "Omit needless code" per S&W.

I was wondering if someone was going to notice that Wink

>Have to disagree on comments

I see your point. I comment quite heavily at the function level, less so inside the braces.

Thanks all for the comments. Make sure to check out James Golick's take on the same subject. Good stuff.

James Devlin on 10/14/2008 7:21:00 AM (84 days ago)

I love how you repeated "Omit needless code" per S&W.

Noah Slater on 10/14/2008 7:57:30 AM (84 days ago)

Amazing article and Strunk and White does sound truely fascinating. I wonder if strunk and white would have been genius programmers in this modern day and age!

Poker is Rigged | Forums on 10/14/2008 12:34:24 PM (84 days ago)

It's always seemed to me that coding and writing are both accomplishing the same purpose, in different domains. Both are the expression of an idea. A program is nothing more than an idea expressed and constrained by language... whether its bits and bytes or Python or brainfuck.

The next generation of programming languages will utilize more artistic and intuitive approaches to such expression. Language itself is too limiting, so interaction with visual elements as symbolic representations of ideas in themselves will create a whole new mode of expression for programmers.

Anonymous on 10/14/2008 2:43:34 PM (84 days ago)

Speaking of the 'brainfuck' language. I had a chance to play around with this the other day. Declarative languages are like rainbow quintets budding on the orange side of the taco rock lobster who never had a chance. Surf's up.

Egregious on 10/14/2008 3:48:03 PM (84 days ago)

Are writing and programing different? Ask some one whom studies linguistics, I think the answer will be intresting.


Anonymous on 10/14/2008 4:17:06 PM (84 days ago)

My favorite part of Elements is the part about "flammable" and "inflammable," and I'm curious as to how this would be converted for programmers.

Dave Vogt on 10/14/2008 5:47:52 PM (84 days ago)

I see tring's point. I've always been a proponent of thoughtful comments - explain why something works, not how it works.

However, I too started working with a large enterprise system recently (SAP). The code base is bigger than I can comprehend. It didn't take long to figure out that nothing replaces self-documenting code.

I still love thoughtful comments, but they aren't helpful when they're in a language you don't speak or read (in this case, German).

Anonymous on 10/15/2008 9:22:21 AM (83 days ago)

I truly hate this book. It was rammed down my throat in high school and college, then rammed down my throat some more when I did some newspaper work, and now that I've escaped to a programming career, I thought I was safe but...nope. It's being rammed down my throat once more.

I enjoy your blog but...Strunk and White? Strunk and White is for nerdz.

Anonymous on 10/15/2008 10:30:00 AM (83 days ago)

I wonder if there is any correlation between a programmer's writing skills to his/her programming skills. It would make an interesting interview question to make a programmer write a paragraph or two about something.

What I want to know is why I always felt like I was missing something in writing classes. I always felt like I had to put forth twice the effort as the other students, and then got half the grade. On the other hand programming has always come naturally to me.

Jon Snyder on 10/15/2008 2:19:21 PM (83 days ago)

This is excellent! I've been a coder for forever, and generally don't see eye-to-eye with English types (although my recent engagement to an English major may well belie that fact... anyway). The ONE book I remember most from English study was Strunk and White! "Omit needless words" is a wholly useful mantra, in writing, code, or otherwise.

Excellent article! I'm glad I ran across it.

Chip Lynch on 10/16/2008 3:02:33 PM (82 days ago)

Not really a new idea.
www.amazon.com/.../0070342075
en.wikipedia.org/.../The_Elements_of_Programming_Style_(book)

Anonymous on 10/20/2008 11:31:58 PM (77 days ago)

I tend to agree with your philosophy on comments and self-documenting code. In my years as a developer working in various teams, I've run into several situations and have arranged in order from what I personally find to be least desirable to most desirable:

1) Programmer writes sloppy code and fails to comment it at all.

2) Programmer writes horrific code that is extremely unclear and then writes pages and pages worth of comments to try to explain its intent. Often the comments are almost as unclear as the code, not just because of the verbosity, but because the unclear nature of the code usually leads to a bad interface that is hard to use, and often that programmer will try to clarify the usage with weird terminology that only makes sense to him/her.

3) Programmer writes good, clean, self-documenting code with easy-to-use interfaces but puts comments all over the place down to almost every variable and constant. Even for things like a named constant, pi, they'll comment that 'it's pi'.

4) Programmer writes good code but is a little slack when it comes to commenting. These developers tend to overestimate the self-documenting aspect of their code a little too much, however, and fail to comment as much as they should.

5) Programmer writes good code and focuses primarily on commenting interfaces rather than implementations. For implementations, they comment only when the code/algorithm is complicated or not well-known.

Anonymous on 10/21/2008 1:17:45 PM (77 days ago)

(Continued) 5 is ideal to me because I believe too many developers 'leak' implementation details into their public interfaces. This could be in the form of documentation. If I'm looking at a header in a C/C++ file, I shouldn't have to concern myself with the implementation details of the functions/classes that are declared in that header. The most important, and most widely consulted documentation by the entire team should relate to usage.

Ideally the time spent by other programmers looking at another programmer's implementation should be minimal in a good, well-maintained system. That's not always the case and it can be unavoidable at times (for example, if the original author gets assassinated by a group of scantily-clad ninjas), but it should be a goal that modern developers strive to achieve. In such cases, if the interfaces are good and clear, the implementation should be easy to swap out if it's hard to maintain by another. if that other has a hard time swapping out the implementation even under a clear, well-documented interface, then that developer probably has no business working with that implementation in the first place.

Anonymous on 10/21/2008 1:24:15 PM (77 days ago)

I my short career in programming -- 2.5 years -- I've already seen more than enough time wasted on the creation and enforcement of needlessly specific coding standards, design conventions, and commenting guidelines. Any software development effort that takes itself seriously should have a style guide of this sort as the foundation of its coding standard. Excellent, inspiring, and informative article!

Xyz on 11/10/2008 9:30:55 AM (57 days ago)

I blogged about the same thing a while back: mitch-wheat.blogspot.com/.../...f-composition.html

Mitch Wheat on 11/15/2008 11:39:51 PM (51 days ago)

I wrote a comment with some really similar thoughts over on this blog: compoundthinking.com/.../#comment-277488

Matt Wilson on 12/17/2008 11:06:32 PM (19 days ago)

Comment on this post:

Thanks for your interest in Coding the Wheel. All fields are optional.