Tuesday, July 27, 2010

The Psychology of Syntax: Lemon Meringue Pie, Functional-Style

A lemon meringue pie results from baking in a preheated oven for 10 minutes, or until golden brown, a baked pastry shell filled with a lemon filling produced by stirring and boiling until thick the whisked combination of egg yolks and a sugar mixture obtained from whisking together sugar, flour, cornstarch, and salt and adding water, lemon juice, and zest topped with a meringue, spread to seal the edges at the crust, created by whipping until peaks form the mixture resulting from gradually adding sugar to egg whites whipped until foamy.

Functional style is mathematically elegant, but except in small doses, most people find imperative style a lot more readable (as in the original from which this recipe was derived).

Bon appétit!


  1. 'Ware the strawman. Most functional programs aren't written as one giant expression with no intermediate definitions. The "functional" recipe could just as easily be.

    Lemon filling is the result of stirring and boiling filling-mixture until thick.

    Filling-mixture is the result of adding water, lemon juice, and zest to sugar/flour mixutre.

    Sugar/flower mixture is the result of whisking together sugar, flour, and cornstarch.

    Meringue is the result of whipping sugar/egg mixture until peaks form.

    Sugar/egg mixture is the result of gradually adding sugar to egg until foamy.

    An unbaked pie is a pastry shell filled with lemon filling and topped by meringue.

    A lemon meringue pie is the result of baking an unbaked pie in an oven for 10 minutes or until golden brown.

    Purely functional programming can conceptually be seen as a set of definitions. It's simply a matter of personal taste as to whether the definitions are fairly fine grained (like my example) or very course grained (like yours).

    The important difference between imperative and functional is that in functional programming the order of operations is constrained only by dependencies. This "functional" definition makes it clear that I can make my meringue first or make the filling first...doesn't matter. In an imperative program/recipe it's not so obvious that the two are independent. Determining independence requires a very careful analysis of what's getting mutated when. And, in programs as opposed to recipes, shared references can be be arbitrarily "distant."

    Of course, in the real world, time is such a critical aspect of recipes (e.g. steak has to marinade for 24 hours, pie has to bake for 10 minutes) that you need a much more sophisticated mechanism to express them in functional terms than this toy example.

  2. Thanks, James, for my first comment ever!

    I confess that my use of “functional style” to mean “written as one giant expression” is more snarky than fair. But I think I have seen more such expressions in languages that advertise themselves as functional than otherwise.

    Every usable programming language that I know of lets you construct large expressions, and also lets you break such expressions into smaller named parts, as you have done with my recipe. Whether such decomposition is declarative or imperative is perhaps not such an interesting question (what if you said “Let x be the result of” instead of “x is the result of”? Instant imperativeness! And equivalent to the functional formulation, as long as the scope is local).

    I think we can all agree that regardless of whether the language you're using is billed as functional or imperative, you need to be careful about using mutable data outside a local scope, particular if there is any possibility of concurrent execution.

    But the question more in my mind when I wrote this was, What makes a programming language readable? There's no shortage of discussion about this topic, but not much in the way of firm conclusions, except that COBOL is not the way to go.

    What contributions do delimiters, keywords, and operator position (prefix vs. infix vs. postfix) make towards rendering a language more or less understandable? Are those of us who speak European languages fond of infix operators because that's where our verbs go? Do Japanese speakers (who put their verbs at the end) understand a postfix language like Forth more easily than we do?

  3. bake andThen preheat (_.color == GoldenBrown)...