Content

Not quite a Yegge long.

Skinning Cats, Functional Purity, Subtle Failure, and You

Friday 9 April 2010 - Filed under Uncategorized

It’s been said that there are many ways to skin a cat. I imagine that’s true, although I haven’t felt the need to explore any of them, let alone enumerate them all. Assuming that various methods exist, however, it’s reasonable to then assume that they have a range of advantages and disadvantages. Perhaps one method optimizes for speed, and another optimizes for usability of the hide. Perhaps there are methods that are better if you intend to eat the cat, and others that are better suited if you’re just interested in the fur.

Similarly, there are many ways to write a program – or rather, many ways to express the same computation. They too express a range of characteristics – speed of execution, readability, memory usage, text length, etc – and just as in the cat scenario, different expressions of the same computation are better suited to different contexts. If you’re writing against the raw metal and you’ve got a few KB of RAM, you’re going to choose different expressions than you might if you’re running on a multi-GHz desktop beast, with a garbage collected environment and a few gigabytes of elbow room. It also depends on what other experience you bring to the programming task – if you grok abstract algebra, or any of the various process calculi, chances are your solutions look quite different from someone whose idea of computation is firmly rooted in the concrete von Neumann idiom of getting things done by mutation of memory locations.

Of course, surrounding each of the correct but radically different expressions of the same computation there’s a much wider range of things that don’t work, even though at a glance, they look as though they ought to. Gross misbehaviour is not so much of a problem, since you can see it; subtlety is what wastes our time. My core assertion in this essay, then, is that the role of software tools, processes and paradigms is, or at least ought to be, to convert as much of that subtly-wrong space into blatantly-wrong as possible.

This isn’t really a new idea. Structured programming was an improvement over spaghetti, since it was easy to write subtly wrong spaghetti. Declarative programming is a good thing, since given our mental model of the machine is going to be different from reality *anyway*, we may as well make it *really* different, and get some value out of that. Powerful type systems are an improvement over less powerful systems, since they convert subtle runtime misbehaviour into blatantly obvious compilation failures. Automatic parallelization, isolation of state, etc are improvements over manual concurrency, since they turn at least some of that incredible breeding-ground of failure – concurrency bugs – into properties that can be proven by the machine. Automated tests are an improvement over ad-hoc testing (or none at all), since they turn some more subtle failures into red bars.

Here’s the next one: carefully controlling side-effects (and their order) by isolating them to a small section of your program is an improvement over having side-effects spread everywhere, since it makes side-effect-related mistakes obvious and localized. Enforcing functional purity (and in particular referential transparency) everywhere else gives you *more* flexibility to express your program in a way that optimizes for whatever attribute you’re interested in, since you can ignore the order in which things happen. Freedom to extract, reorder or inline expressions as you need to, without worrying about whether that’s going to change the semantics. If it’s more readable to recompute an expression than to carry the value around, you should be able to do that without having to figure out if you’re going to get two writes to your database as a result.

Of course, there’s no really new ideas here either. Even in the state-happy willy-nilly-mutation world of classic OO, we’ve had things like separation between mutators and queries [in Fowler, but the idea is much older than his book].

So, in closing: On the surface, it looks like purity and referential transparency, applied to most of your program is a potentially difficult restriction, but if it allows you to explore the space of *correct* expressions of your program without  inadvertently wandering into the subtly incorrect… that’s a fantastic thing.

Less worrying about correctness gives you more freedom to pursue whatever other attribute you’re really after. All you’ve got to do is keep your functions pure.

2010-04-09  »  admin

Talkback x 4

  1. All Hit Lyrics
    10 April 2010 @ 9:47 am

    Thanks for sharing, I found this story, while searching for some downloads and ran across this site, useful comments and good points made.

  2. Rigoberto Tattersall
    26 April 2010 @ 6:14 am

    Can I link to this webpage, from my web site? I’m wanting to gather as many snippets of useful information as I can.

  3. Carri Lamaster
    2 May 2010 @ 7:30 pm

    Wow, great blog.Really looking forward to read more. Keep writing.

  4. MarkSpizer
    3 May 2010 @ 7:15 pm

    great post as usual!

Share your thoughts

Re: Skinning Cats, Functional Purity, Subtle Failure, and You







Tags you can use (optional):
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>