On bread recipes, maps, and intentions

[I’ve been quiet for the past three weeks–not because I have less that I want to talk about, but because I have more. Major wheels turning in my head. I’m having a hard time getting from the “intuited ideas” mode to the “crisp enough to put it in writing” mode, though. Consider this a down payment on some future discussions…]

One of my mother’s talents is bread-making. She’s been kneading and baking and pulling beautiful loaves out of the oven for as long as I can remember. Bread is one of the ways she says “I love you” to family and friends.

A few years back, she created a cookbook full of family recipes, and gave one to each adult child for Christmas. I was struck by how she began the bread section. Instead of launching right into the recipes, she included a couple of pages of “bread theory”, if you will. The section about water is typical:

“Water — Just about any edible liquid could be used as the base for bread. Some that come to mind are vegetable cooking water, potato water, milk, and so on. There is no problem with substituting any of these for liquid called for in a recipe, but you should keep in mind that if the liquid is salty, the salt should be adjusted; if the liquid is sweet, the sugar should be adjusted… Fresh milk can be a problem because of enzymes that would prevent yeast action. For this reason, most old recipes that call for milk specify that the milk be scalded first. This isn’t necessary if you are using water and powdered milk, but remember that the mechanics of the recipe probably depend on at least warm milk (so use warm or even hot water).”

If you’re wondering why I am writing about bread recipes in this blog that focuses on software craftsmanship, consider how much that paragraph resembles a really high-value comment in source code.

It has to do with principles and intentions.

Software is all about recipes, right?

Recipes are a lot like software algorithms (especially in imperative programming styles): First, do this; next, do that; wait 25 minutes; return new Loaf()… We even talk about “recipes” and “cookbooks” when we make catalogs of software techniques.

How is this metaphor instructive… or worrisome?

Continue reading

When good comments mean bad language

I’ve had an epiphany.

For years, I’ve urged developers to write better comments. I still claim that’s a good idea (a very good one), but as I’ve pondered what a better programming language might look like, I’ve come to an important conclusion:

A lot of “best practice” commenting is just workarounds for inadequate language design.

This might seem like a crazy or arrogant claim. The Wirths and Matsumotos and Hejlsbergs and van Rossums and McCarthys of the world are incredibly smart people; how could I claim to know something that they do not? Each of these language designers has probably forgotten more about computer science than I will ever learn.

And yet, I think Randall Munroe (the cartoonist at xkcd) was right to make fun of our industry’s facile assumption that context-free grammar is all you need to know about formal language:

image credit: xkcd.com

To show you what I mean, I’ve inlined snippets of code from a variety of programming languages below. Don’t worry about digesting them carefully right now, but give them a quick glance and then move on to my analysis, and see if you agree with my claim about an unhealthy pattern. Continue reading

2 Surprising Truths About The Iron Triangle

Project management 101 teaches that, when managing outcomes, you cannot alter scope, schedule, or cost (resources) without affecting at least one of the other dimensions. This interrelationship is known colloquially as the “Iron Triangle.” Sometimes we put “quality” in the middle to show how it is unavoidably shaped by choices on the other constraints:

Image credit: John M. Kennedy T (Wikimedia Commons)

Lots of Dilbert cartoons derive their humor from the unwillingness of the Pointy Haired Boss (PHB) to acknowledge this relationship. These cartoons are funny because they are so eerily similar to conversations we’ve all had, where someone wants us to deliver ultra-high quality, on a limited budget, in an aggressive timeframe, with a boatload of features.

It ain’t gonna happen, folks. We engineers are clever, but we’re not magicians. Triangles don’t work that way.

You’ve learned some good principles when you can articulate this geometry lesson.

But there’s more.

Truth 1: Scope is a trickster

Many well meaning managers and executives understand this trilemma, and they distance themselves from Dilbert’s PHB by acknowledging that something has to give. “I pick scope,” they’ll say. “We absolutely must have the product before the summer doldrums, and we only have X dollars to spend, but I’m willing to sacrifice a few features.”

This can give product management heartburn–feature sets sometimes hang together in ways that make slicing and dicing dangerous. An airplane that’s good at takeoffs but that can’t land is unlikely to be a commercial success. Good product managers will point this out, and they’ll be right.

Continue reading

Good fences make good neighbors

In Robert Frost’s poem, “Mending Wall”, two farmers meet each spring to rebuild the rock wall between their properties. One farmer is the narrator. He notes that the unseen forces of winter and weather always cause some decay (“something there is that doesn’t love a wall”), and he wonders why the wall is necessary. There’s apple orchard on one side, and pine forest on the other–it’s not as if something will be kept in or out. The other farmer answers with the repeated aphorism “good fences make good neighbors.”

photo credit: DragonWoman (Flickr)

This poem could be a treatise for the principle of encapsulation in software. In software as in life:

  • Something there is that doesn’t love a wall.
  • Good fences make good neighbors.

What doesn’t love a wall?

Subroutines, formal interfaces, data hiding, class hierarchies, the pimpl idiom, and similar mechanisms all create barriers in software between consumers and providers of functionality. These techniques are well known, but we still have codebases littered with protected data members, unnecessary class declarations in headers, goto, and other suboptimal choices.

Why? Continue reading

Why Your Software Should Cry

The problem of pain has bothered philosophers–particularly those with a religious bent–for a long time. What might be the purpose of suffering, they’ve wondered, and how does it relate to the human experience?

But pain barely impinges on the thinking of software engineers at all. Computers never wince, or complain, or mourn the loss of a favorite program (Marvin the paranoid android excepted). An OS runs at full speed until the instant when its kernel “panics” without warning; once you reboot, it acts as if nothing ever happened. No sniffles, no whimpers, no scabs…

photo credit: nanny snowflake (Flickr)

This is unfortunate.

Reaction to stimuli is one of the 8 characteristics of life. That means that living things are aware, in some sense, of their relationship to the larger environment. They distinguish between good and bad stimuli. They hurt. And they learn from their pain.

Lessons from a protist

This ability to use pain is not limited to complex organisms. The lowly Stentor roeselii (a single-celled protozoan that anchors for filter feeding) exhibits an incredible repertoire of behaviors to optimize its relationship with the environment. Squirt it with water from a pipette, and it contracts for defense. 30 seconds later, it unfurls again. Keep squirting, and it eventually learns to ignore the false alarms.

Gently introduce a poison into the water current, Continue reading