Infinite Application

Summary: Function application is a key concept in lambda calculus. While it is commonly expressed using parentheses in Clojure, it is also reified into a function that itself can be applied to another function.

Function application in Clojure is easily expressed with a couple of parentheses:

(foo 1 2 3)

That's the function foo applied to the arguments 1, 2, and 3. But let's say we have those numbers in a vector somewhere, and we want to call foo on them.

(def some-numbers [1 2 3])

We could manually pull out the arguments from the vector like this:

(foo (some-numbers 0) (some-numbers 1) (some-numbers 2))

Great! That should work. But more commonly you see this:

(apply foo some-numbers)

apply means take the function (the first argument) and apply it to the arguments which are in the list (the last argument). apply pulls out the values from the list internally so you don't have to.

apply is a function you'll see in many Lisps. It plays a key role in the meta-circular evaluator as defined in The Structure and Interpretation of Computer Programs (SICP). In the meta-circular evaluator, eval and apply are defined in terms of each other.

The way eval is defined classically, (foo 1 2 3) gets turned into (apply foo [1 2 3]) internally. This means that you can replace (foo 1 2 3) with (apply foo [1 2 3]) in the program without changing the meaning.

But! Since apply is a function, (apply foo [1 2 3]) is equivalent to (apply apply [foo [1 2 3]]), which is equivalent to (apply apply [apply [foo [1 2 3]]]). And you can expand that out forever. (Please don't!).

apply is something I really love about Lisp. It takes one of the main parts of lambda calculus (function application) and reifies it. Function application is available as a function, which can be passed around, composed, etc, just like any other value. I love it!

If you're in love with this idea, too, you might want to check out LispCast Introduction to Clojure. It's my video course about, you guessed it, Clojure. It takes you from absolute parenthesis-phobe to I-never-knew-it-could-be-this-way lisper by using animations, exercises, and screencasts.