Lambda Functions

The LISP family of languages are based, in part, on a mathematical formalism call Lambda Calculus, a notation for recursive functions. While a detailed explanation of lambda calculus is outside of the scope of this tutorial, it is important to understand that in the lambda calculus, there exists classes of functions whose domains and/or ranges are other functions.

In Scheme (and most other LISP derived languages), the form (lambda) is a generator of new functions: given an argument list and a function body, (lambda) returns a function. For example, the following code creates a nameless function and applies it to the list (a (b c) d):

   > ((lambda (x)
                 (if (list? x) (cadr x)
                      #f))
         '(a (b c) d))
   (b c)
  

The function created by a (lambda) can be assigned to an identifier using (define):

   (define second 
     (lambda (x)
       (if (list? x) (cadr x)
           #f)))
  

In fact, the usual notation of

   (define (second x)
     (if (list? x) (cadr x)
         #f))
  

is nothing more than a shorthand for the (lambda) version, in the form of a syntax macro. This is also true of several other structures, including (let) and (begin).

But (lambda) is more than just a peculiar way of defining ordinary functions: it allows you to generate functions programmatically, at runtime. For example, the following function takes two other functions and composes them:

   (define compose
     (lambda (f g)
       (lambda (arg)
         (f (g arg)))))
  

This can be then used like so:

   > ((compose (lambda (y) (* 2 y))
                  (lambda (z) (+ 3 z)))
         5)
   16

   > ((compose (lambda (x) (* x x)) sqrt) -1)
   -1
  

Lambda expressions may be used anywhere a function could be expected.

Contents Previous Next