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.