Next: Lexical Binding, Previous: Special Forms, Up: Special Forms
A
lambda
expression evaluates to a procedure. The environment in effect when thelambda
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 thelambda
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 predicatedefault-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
, andc
are all required. The procedure must be passed exactly three arguments.(a b #!optional c)
a
andb
are required,c
is optional. The procedure may be passed either two or three arguments.(#!optional a b c)
a
,b
, andc
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
andb
are required,c
andd
are optional, ande
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
The
named-lambda
special form is similar tolambda
, 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 asnamed-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