Next: , Previous: Special Forms, Up: Special Forms


2.1 Lambda Expressions

— special form: lambda formals expression expression ...

A lambda expression evaluates to a procedure. The environment in effect when the lambda expression is evaluated is remembered as part of the procedure; it is called the closing environment. When the procedure is later called with some arguments, the closing environment is extended by binding the variables in the formal parameter list to fresh locations, and the locations are filled with the arguments according to rules about to be given. The new environment created by this process is referred to as the invocation environment.

Once the invocation environment has been constructed, the expressions in the body of the lambda expression are evaluated sequentially in it. This means that the region of the variables bound by the lambda expression is all of the expressions in the body. The result of evaluating the last expression in the body is returned as the result of the procedure call.

Formals, the formal parameter list, is often referred to as a lambda list.

The process of matching up formal parameters with arguments is somewhat involved. There are three types of parameters, and the matching treats each in sequence:

Required
All of the required parameters are matched against the arguments first. If there are fewer arguments than required parameters, an error of type condition-type:wrong-number-of-arguments is signalled; this error is also signalled if there are more arguments than required parameters and there are no further parameters.
Optional
Once the required parameters have all been matched, the optional parameters are matched against the remaining arguments. If there are fewer arguments than optional parameters, the unmatched parameters are bound to special objects called default objects. If there are more arguments than optional parameters, and there are no further parameters, an error of type condition-type:wrong-number-of-arguments is signalled. The predicate default-object?, which is true only of default objects, can be used to determine which optional parameters were supplied, and which were defaulted.
Rest
Finally, if there is a rest parameter (there can only be one), any remaining arguments are made into a list, and the list is bound to the rest parameter. (If there are no remaining arguments, the rest parameter is bound to the empty list.) In Scheme, unlike some other Lisp implementations, the list to which a rest parameter is bound is always freshly allocated. It has infinite extent and may be modified without affecting the procedure's caller.

Specially recognized keywords divide the formals parameters into these three classes. The keywords used here are ‘#!optional’, ‘.’, and ‘#!rest’. Note that only ‘.’ is defined by standard Scheme — the other keywords are MIT/GNU Scheme extensions. ‘#!rest’ has the same meaning as ‘.’ in formals.

The use of these keywords is best explained by means of examples. The following are typical lambda lists, followed by descriptions of which parameters are required, optional, and rest. We will use ‘#!rest’ in these examples, but anywhere it appears ‘.’ could be used instead.

(a b c)
a, b, and c are all required. The procedure must be passed exactly three arguments.
(a b #!optional c)
a and b are required, c is optional. The procedure may be passed either two or three arguments.
(#!optional a b c)
a, b, and c are all optional. The procedure may be passed any number of arguments between zero and three, inclusive.
a
(#!rest a)
These two examples are equivalent. a is a rest parameter. The procedure may be passed any number of arguments. Note: this is the only case in which ‘.’ cannot be used in place of ‘#!rest’.
(a b #!optional c d #!rest e)
a and b are required, c and d are optional, and e is rest. The procedure may be passed two or more arguments.

Some examples of lambda expressions:

          (lambda (x) (+ x x))            ⇒  #[compound-procedure 53]
          
          ((lambda (x) (+ x x)) 4)                ⇒  8
          
          (define reverse-subtract
            (lambda (x y)
              (- y x)))
          (reverse-subtract 7 10)                 ⇒  3
          
          (define foo
            (let ((x 4))
              (lambda (y) (+ x y))))
          (foo 6)                                 ⇒  10
— special form: named-lambda formals expression expression ...

The named-lambda special form is similar to lambda, except that the first “required parameter” in formals is not a parameter but the name of the resulting procedure; thus formals must have at least one required parameter. This name has no semantic meaning, but is included in the external representation of the procedure, making it useful for debugging. In MIT/GNU Scheme, lambda is implemented as named-lambda, with a special name that means “unnamed”.

          (named-lambda (f x) (+ x x))    ⇒  #[compound-procedure 53 f]
          ((named-lambda (f x) (+ x x)) 4)        ⇒  8