Next: , Up: Functions   [Contents][Index]


5.9.1 Lambda Expressions

Lambda expressions are used to create functions from other Lisp objects. A lambda expression is a list whose first element is the symbol lambda. All functions written in Lisp (as opposed to the primitive functions in C) are defined using lambda expressions.

The general format of a lambda expression is:

(lambda lambda-list [doc] [interactive-declaration] body-forms… )

Where lambda-list is a list defining the formal parameters of the function, doc is an optional documentation string (see Docstrings), and body-forms is the sequence of forms making up the function body, evaluated using an implicit progn.

interactive-declaration is an obsolete feature, only required by interactive commands5.

The lambda-list is a list, it defines how the values applied to the function are bound to local variables which represent the parameters of the function. At its simplest it is simply a list of symbols, each symbol will have the corresponding argument value bound to it. For example, the lambda list (x y) defines two parameters, x and y. When called with two arguments the first will be bound to the variable x, the second to y. When used in a full lambda expression this looks like:

(lambda (x y)
  (+ x y))

this evaluates to an anonymous function with two parameters, x and y, which when called evaluates to their sum. More on evaluation is described in the next section, See Closures.

There are several lambda-list keywords which modify the meaning of symbols in the lambda-list. The syntax of the lambda list is:

([required-parameters…]
 [#!optional optional-parameters…]
 [#!key keyword-parameters…]
 [#!rest rest-parameter | . rest-parameter])

Each lambda list keyword is a symbol whose name begins ‘#!’, they are interpreted as follows:

#!optional

All variables following this keyword are considered optional (all variables before the first keyword are required: an error will be signalled if a required argument is undefined in a function call).

optional-parameters may either be of the form symbol or of the form (symbol default). If no argument is supplied for this parameter the default form is evaluated to give the bound value6. If no default form is given, then the variable is bound to a false value.

Note that optional parameters must be specified if a later parameter is also specified.

((lambda (#!optional a b)
   (list a b)))
    ⇒ (() ())
((lambda (#!optional a b)
   (list a b))
 1)
    ⇒ (1 ())
((lambda (#!optional a b)
   (list a b))
 nil 1)
    ⇒ (() 1)
((lambda (#!optional (a 1))
   (list a)))
    ⇒ (1)
((lambda (#!optional (a 1))
   (list a))
 2)
    ⇒ (2)
#!key

This object marks that the parameters up to the next lambda list keyword are keyword parameters. The values bound to these parameters when the function is called are determined not by position (as with normal parameters), but by being marked by a preceding keyword symbol. Keyword symbols have the syntax ‘#:symbol’.

As with optional parameters, default values may be supplied through the use of the (symbol default) syntax. If no default value is given and no keyword argument of the specified kind is available, the variable is bound to a false value.

For example, the lambda list (a #!key b c) accepts one required argument, and two optional keyword arguments. The variable a would be bound to the first supplied argument; the variable b would be bound to the argument preceded by the keyword #:b, or () if no such argument exists. (After extracting required and optional arguments, each remaining pair of values is checked for associating a value with each keyword.)

((lambda (a #!key b c) (list a b c))
 1 2 3)
    ⇒ (1 () ())
((lambda (a #!key b c) (list a b c))
 1 #:b 2 3)
    ⇒ (1 2 ())
((lambda (a #!key b c) (list a b c))
 1 #:b 2 #:c 3)
    ⇒ (1 2 3)
((lambda (a #!key b c) (list a b c))
 1 #:c 3 #:b 2)
    ⇒ (1 2 3)
#!rest

The #!rest keyword allows a variable number of arguments to be applied to a function, all the argument values which have not been bound to argument variables (or used to mark keyword arguments) are made into a list and bound to the variable following the #!rest keyword. For example, in

(lambda (x #!rest y) …)

the first argument, x, is required. Any other arguments applied to this function are made into a list and this list is bound to the variable y.

Variable argument functions may also be defined through the Scheme method of using an improper lambda-list. The previous example is exactly equivalent to:

(lambda (x . y) …)

When a function represented by a lambda-list is called the first action is to bind the argument values to the formal parameters. The lambda-list and the list of argument values applied to the function are worked through in parallel. Any required arguments which are left undefined when the end of the argument values has been reached causes an error.

After the arguments have been processed the body-forms are evaluated by an implicit progn, the value of which becomes the value of the function call. Finally, all parameters are unbound and control passes back to the caller.


Footnotes

(5)

Only used when Librep is embedded within another application.

(6)

The default form is evaluated in the environment of the closure being called, but without any of the bindings created by the lambda expression.


Next: , Up: Functions   [Contents][Index]