Mountains, Molehills, and Markedness

In my previous three posts, I explained why the semantics of programming languages are not as rich as they could be. I pointed out some symptoms of that deficit, and then made recommendations about bridging the gap. Finally I introduced “marks”–a feature of the intent programming language I’m creating–and gave you a taste for how they work.

In this post, I’m going to offer more examples, so you see the breadth of their application.

Aside

Before I do, however, I can’t resist commenting a bit on the rationale for the name “marks”.

In linguistics, markedness is the idea that some values in a language’s conceptual or structural systems should be assumed, while others must be denoted explicitly through morphology, prosodics, structural adjustments, and so forth. Choices about markedness are inseparable from worldview and from imputed meaning. Two quick examples:
Continue reading

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

Don’t forget the circuit breakers

Recently I’ve been pondering an interesting book called Release It!, by Michael Nygard. It’s full of anecdotes from someone who has spent a major portion of his career troubleshooting high-profile crashes of some of the most complex production software systems in the world–airline reservations, financial institutions, leading online retailers, and so forth.

circuit breaker

A circuit breaker. Photo credit: Wikimedia Commons.

One design pattern that Nygard recommends was new to me, but it rang true as soon as I saw its description. Like many classic patterns, I’ve implemented variations on it without knowing the terminology. I like Nygard’s formulation, so I thought I’d summarize it here; as I’ve said before, good code plans for problems.

The pattern is called circuit breaker, and its purpose is to prevent runaway failures.

In systems without circuit breakers, failures in an external call may cause an exception on the caller’s side; this can cause the caller to log, retry, and/or execute other specialized logic. Since errors are supposed to be the corner case, the blocks of code that handle them are often expensive to execute. The very slowness of the error-handling codepath can be the source of further failures, because locks are held longer than normal, or because we poll until a connection is restored, overwhelming a system that’s already limping.

Or, to borrow an old idiom, “it never rains but it pours.”

In the circuit breaker pattern, on the other hand, the caller assigns each “circuit” (a codepath that invokes an external entity) to one of three possible states: closed, open, or half-open. Continue reading