Friday, January 18, 2013

Higher-Order Functions: What Are Their Analogues In Human Grammar?

Get ready for some epic hand-waving.

I'm reading Reg Braithwaite aka Raganwald's new book JavaScript Allongé, and -- because it's a Leanpub book and therefore to some extent a work in progress -- subjecting it to some pretty merciless copyedits as I go.

JavaScript Allongé explores JavaScript in detail, from the perspective of a Lisper with a console and a curious mind. I don't think the book contains a word about either concurrency or the DOM. Instead, it pokes its way through JavaScript itself, taking things apart to see how they work, like a curious gnome enjoying a leisurely stroll through a giant machine. Or like Donald Duck In Mathmagic Land, but with a strong emphasis on higher-order functions.

From the book's blurb:

JavaScript Allongé emphasizes functions as first-class values, and topics built on functions such as objects, prototypes, "classes," combinators, method decorators, and fluent APIs. JavaScript Allongé begins at the very beginning and progresses step by logical step through JavaScript's unique approach to functions, idioms, and even syntactical peculiarities, so that by the end of the book you'll have worked your way from the simplest of functions up to combinators that create method decorators for use with classes and objects.

Anyway, I want to pick at one of the specific metaphors in the book:

Pure functions that act on other functions to produce functions... are the adverbs of programming.

As I understand it, the argument goes like this: higher-order functions resemble adverbs because functions resemble verbs, and higher-order functions modify functions. Functions resemble verbs because they represent actions, rather than objects, although that's a bit tricky since functions basically are objects in JavaScript. All in all, it's a reasonable argument, but I disagree with it.

I disagree because there's more than one way to modify a verb, and if you want to draw parallels between the grammar of human language and the way programming languages work, you have many, many human languages to choose from. Different languages modify verbs in different ways.

My favorite human language is Attic Greek, the dialect of Ancient Greek which Plato, Aristotle, and their contemporaries in Athens used. Attic Greek, and Ancient Greek in general, features an astounding and complex range of prepositions.

Prepositions modify verbs by indicating the manner in which a verb operates. We have them in English; for instance, consider the difference between talking to a person and talking at a person. "To" and "at" are prepositions, and they modify the meaning of the verb "to talk."

Ancient Greek prepositions are more numerous, more subtle, more sophisticated, and more powerful than English prepositions. Here's a diagram of some of the more popular Greek prepositions:

As pretty as that is, you'll probably get more mileage out of this version, with transliterations and annotations in English:

What makes prepositions so important in Ancient Greek? To quote a web site on the topic:

Prepositions are often combined with verbs to form compound words.

(That web site has a religious perspective on the language; this happens often, because the core religious text of Christianity was written in a dialect of Ancient Greek. You can get all the linguistic benefit and ignore the religious content if you like. It's certainly how I approach the topic.)

Anyway, you can fuse Ancient Greek prepositions onto verbs, and you can also fuse them with each other. You can do a tiny smidgen of this in English -- consider the extremely relevant English term "overthinking" -- but Greek takes it to dizzying heights. For a wonderful, lurid example, Ancient Greek used compound verbs to describe sexual positions. Different sexual positions got their own verbs. Prepositions would fuse with each other and the verb itself to describe the exact way in which the verb occurred. So the translation for "doggy style" would be something like "kata-eis-fucking," or "behind-into-fucking." Some pornographic orgy situation might get a term like "inbetweenalongwithfucking." ("Meta" might be in there somewhere, too.) Sex in public would only need one preposition and one verb: "emprosthen-fucking," or "fucking-in-the-presence-of."

By the way, I think German features a similar approach to verb construction, but I don't know for sure. Also, if the lugubrious nature of the example disturbs you, that Bible web site features less provocative examples:

Prepositions are often combined with verbs to form compound words. The effect of the preposition on the meaning of the verb varies, but we can loosely categorize most of these effects as follows:

1. The meaning of the preposition is combined with the meaning of the verb.
For example βαίνω means "I go." Remember that κατά can mean down. Accordingly, καταβαίνω means "I go down."

I know some of you are thinking "that's what she said" right now. I've met my readers, and I'm very familiar with your level of maturity. But I'm sure we can find something calmer in a subsequent paragraph:

2. The meaning of the verb is intensified. Compounds intensified by a prefixed preposition are sometimes called "perfectives" because the action is viewed as carried out to perfection, i.e. to completion. For example, ἐσθίω means "eat," but when κατά is prefixed to form κατεσθίω, the meaning is "devour" (see κατεσθίω used in Mk. 12:40). Here, perhaps we see something reminiscent of an English idiom that makes the Greek seem less strange. If we talk about some one devouring his food, we may say "he eats it up."

OK, now I bet my female readers are thinking "that's what he said". I should have known this was going to end badly. Anyway, in the same way that you can combine prepositions with verbs to form new verbs in Ancient Greek, you can combine higher-order functions with other functions to form new functions in JavaScript, Lisp, Ruby, Perl, or any language which supports higher-order functions.

Because of this, I think using adverbs as a metaphor to describe higher-order functions is the wrong way to go. However, since you write code to understand it later, and English lacks the preposition-fusing features of Ancient Greek, I find that in real life, I tend to name my higher-order functions with the present participle.

Present participles modify a verb in a clause. Speaking in terms of this sentence, I'm using "speaking" as a present participle to modify the verb "using," and I'm using "using" to modify "modify" (twice!). Present participles in English make good names for higher-order functions because, like adverbs and Greek prepositions, they modify verbs. But I think they make better verb-modifiers in English than adverbs do, because they add parallel, ongoing action to verbs, while adverbs add characteristics or context.

I got this pattern from Rails several years ago, but I don't remember the name of the exact method, and the best example I can find in the current codebase doesn't quite fit. For the sake of argument, here's a CoffeeScript example instead.

Here contradicting is the present participle, while deny and affirm are straight verbs.

In Ancient Greek, you could use ἀντί, which conveys opposition and sort of means "against." The word inspired, sounds like, and roughly corresponds to our "anti," as in "anti-war movement" or "anti-pong," the quirky British slang for "deodorant." ("Pong" is the British word for a minor but offensive odor. It also functions as a verb, i.e., "these old, dirty socks pong a bit.")

With ἀντί, you have the disadvantage that understanding Ancient Greek prepositions requires specialized knowledge, and programmers are hard enough to hire as it is. But the advantage is that you can chain Greek prepositions almost endlessly, while endless chains of present participles in English can look a bit odd.

I think that's actually a big deal. I suspect that if most programmers knew Ancient Greek, you'd see a lot more functional programming.

"Sapir-Whorf" is a recurrent meme from the last several years of programming discussion. It refers to research by linguists which show that the language you use shapes your thoughts. I'm told that the way programmers use the term misrepresents the linguistic research, so I bring up the topic reluctantly, but the meme spreads and survives because everybody who's worked with a few very different programming languages needs a word for the different modes of thinking you experience from language to language.

Consider how complicated it is to talk about this in English, and compare that to how simple it would be if all I had to say was "you chain higher-order functions the same way you chain prepositions when you want to describe a sexual position." An entire way of conceptualizing action, which requires an unbelievably erudite point of view for an English speaker, required nothing more than knowledge of the crudest slang for a speaker of Ancient Greek.

This is because Ancient Greek expresses some ideas with a subtlety and nuance which English can't match, and its preposition-fusing compound verbs play an important role in that. When you write code with higher-order functions, you often chain them together in complex ways, so the analogy's very close. But, if you haven't studied Ancient Greek, I think present participles function better as an analogy for higher-functions than adverbs do.

However, I hope it's obvious that if this is the biggest complaint I have about a book, then I have to call it a pretty thought-provoking book.