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.
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.
__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:
- Generics / Templates
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:
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.
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.
Bringing Down the House by Ben Mezrich is, so far as I know, the only book which has ever succeeded in writing about the game of blackjack in an interesting way.
No offense to blackjack authors/players, but blackjack suffers from the same problem that afflicts poker: it can be a lot of fun to play, but often not much fun to read about playing. As an old blackjack-pro-turned-poker-player once wrote:
Blackjack is a game of pure numbers and rote, algorithmic strategy, and the life of a professional blackjack player (as professional blackjack players will agree) can be an exceedingly dull grind. Why should anybody contend with huge variance relative to a measly 1-2% gain, hostile casino staff, and hours of never-ending boredom? Masochism? For this reason, I believe that inside every casino blackjack player is a poker player, waiting to get out. In poker, the edge is a fat 10%, 15%, 20% by some estimates. In poker, there is no hostile casino staff, only people who are glad you showed up to play. In poker, you can make more money in a year than many people will make in a decade, and you can do this even if you’re not a world-class player. Compared to blackjack, the game of poker is like a breath of fresh air.
For this reason, I think Bringing Down the House is a work of real genius. It does the impossible: injects life back into the game of blackjack. Even if the story is a fraud, as a recent article in the Boston Globe questions: who cares. The story is what sells. And this story sold so well that it was turned into a major motion picture: 21.
21 tried to do for blackjack what Rounders did for poker. And okay, it failed. But from this forgettable jumble of poorly written, poorly acted scenes, we can extract one gem. It’s the scene in which Kevin Spacey presents our hero with a puzzle:
Suppose you’re on a game show, and you’re given the choice of three doors: Behind one door is a car; behind the others, goats. You pick a door, say No. 1, and the host, who knows what’s behind the doors, opens another door, say No. 3, which has a goat. He then says to you, “Do you want to pick door No. 2?” Is it to your advantage to switch your choice?
Welcome to the Monty Hall problem, which is admirably explained in layman’s terms here, and demonstrated using Bayesian maths here.
The correct answer is: yes, by switching doors your chance of picking the “right door” goes from 33% to 66%, provided that the host knows which door contains the car. If the host doesn’t know which door contains what and is just picking randomly, then the answer is no: your chances of picking the right door are 50-50.
And if that makes zero sense to you…welcome to the club. As Wikipedia notes:
When the problem and the solution appeared in Parade, approximately 10,000 readers, including nearly 1,000 with Ph.D.s, wrote to the magazine claiming the published solution was wrong.
This problem is still vigorously debated today. In Monty Hall Redux, Brian Hayes explains:
In the July-August issue of American Scientist I reviewed Paul J. Nahin’s Digital Dice: Computational Solutions to Practical Probability Problems, which advocates computer simulation as an additional way of establishing truth in at least one domain, that of probability calculations. To introduce the theme, I revisited the famous Monty Hall affair of 1990, in which a number of mathematicians and other smart people took opposite sides in a dispute over probabilities in the television game show Let’s Make a Deal. (The game-show situation is explained at the end of this essay.) When I chose this example, I thought the controversy had faded away years ago, and that I could focus on methodology rather than outcome. Adopting Nahin’s approach, I wrote a simple computer simulation and got the results I expected, supporting the view that switching doors in the game yields a two-thirds chance of winning.
But the controversy is not over. To my surprise, several readers took issue with my conclusion. (You can read many of their comments in their entirety here.) For example, Bruce Sampsell of Chapel Hill, N.C., wrote:
If you don’t know who to believe, try an interactive version of the puzzle such as the one below by Shawn Olson:
I was just recently introduced to the Monty Hall Game paradox by my friend Andrew Penry. When he first proposed the game to me I thought it was simply absurd—and my intuitive thinking process would not allow me to accept the statistical conclusions that the game entails.
Sit down and play 50 or 100 games, and see whether you end up choosing the right door (or in this case, the right card) 66% of the time, give or take. Here’s how my results looked after 60 games:
That’s a highly unintuitive result from the perspective of anyone who’s been trained to think that past results don’t change the probability of independent future results. Flipping a coin and getting heads 10 times in a row doesn’t change the probability of getting heads on the next flip. Your chances are 50-50, every single time. Similarly, just because the host has revealed 1 of the 3 doors doesn’t change the fact that we’re now presented with a choice between two doors. One door contains a car and one door contains a goat. Ergo, no matter which door you choose, and no matter what happened previously, your chances of picking the right door are now 50%.
That’s rational, makes perfect sense, and yet, like many things in life which are rational and make perfect sense, it’s 100% wrong.
The Harry Potter series is, by all accounts, the most successful fiction in history.
With a few flicks of his magic wand, Harry Potter has turned Rowling into a billionaire (we estimate she’s worth $1 billion). She’s one of only five self-made female billionaires, and the first billion-dollar author.
This is apparent to anybody who lives within earshot of a dedicated Harry Potter fan.
And even the dreaded “Avada kedavra!”
If you’re anything like me, you’ve had imaginary versions of these Harry Potter spells flung at you by over-zealous Harry Potter children, spouses, friends, and neighbors, oh, approximately since the first book came out way back in 1997.
So in the name of all things holy, and on behalf of anyone who’s ever stared down the wrong end of a Crucio spell, I beg whoever is responsible for the Harry Potter empire to relent, and give these people a place to put their encyclopedic knowledge of Harry Potter to use.
Give us a Harry Potter MMORPG.
Let people sign up by the millions and play together. Let them choose a name, create a character, and pick a character class House. Or, answer a few questions and let the Sorting Hat pick one for them:
Let them choose a starting city - er, I mean a school.
Then deposit them in the world of non-Muggles as a Level-1 character first-year student. Force them to attend classes, sneak through the halls of Hogwarts, maybe even play the occasional Quidditch game:
As they gain experience, let them advance through the grades until one day, at Level 7 as a 7th-year student, they graduate. And that’s when the game begins in earnest.
- Will you stay on at Hogwarts and become a teacher?
- Break into Azkaban?
- Join the Ministry of Magic?
- Pursue a career as a professional Quidditch player?
- Open a shop in Hogsmeade or Diagon Alley?
- All of the above?
Or maybe you’ve had it with the civilized world. Maybe you yearn to study (or even hunt) Norwegian Ridgebacks in the wilderness (and it should be vast, as vast as World of Warcraft is vast, with Muggle and non-Muggle partitioning):
Oh and did I mention?
This one is important.
You should be allowed to declare your allegiance to this guy. Or to his memory.
That should spice up the game quite nicely, and allow for meaningful player-vs.-player (PVP) combat against an established backstory.
Practicioners of the Dark Arts vs. those who oppose them.
Give me tactics. Give me tricks. Give me PVP goodness.
And just to make it interesting: let there be hundreds and hundreds of spells, skills, and abilities to choose from.
- Schools of Magic: Divination, Potions, etc.
- Abilities such as Animagi transformation
- Languages like Parseltongue
- Casting without a wand (advanced)
- Flying without a broomstick (also advanced)
Make players research them in libraries, learn them from teachers and friends, go on quests to procure them. Oh, and let them create new spells, new potions, new abilities. I want a fabrication system that’s the equal of anything in Everquest 2 or World of Warcraft. I want in-game, functional versions of the Hogwarts Express; Floo powder; hidden doorways between the Muggle and wizarding realms. I want Pets (owls, cats, toads, and rats) with powers that I can control in-game. I want cloaks of invisibility. And I want a plethora of wands to choose from (or to choose me, because as any Harry Potter fan knows, the wand chooses the wizard, not the other way around), each with slightly different powers.
You hear me, J.K. Rowling? Electronic Arts? Warner Bros.?
Give us a massively multiplayer, online, 3D, interactive, graphically intensive, excruciatingly deep version of Harry Potter. Make another billion dollars while you’re at it. Take World of Warcraft’s 10-million-plus subscriber base, and double it, triple it.
And let your fans—the ones who do this…
…figure out how the story ends.
[Posted on behalf of DLD, a dedicated Harry Potter fan.]