Chapter 4. Foundational library
This chapter will be extended by a future fascicle.
1. Procedures
(lambdaformalsbody)
SyntaxFormals is a formal parameter list as
described below, and body is a body as described by .
SemanticsA lambda expression evaluates to a
procedure. The environment in effect when the lambda expression is evaluated is remembered as part of the procedure.
When the procedure is later called with some arguments, the
environment in which the lambda expression was
evaluated is extended by binding the variables in the parameter
list to fresh locations, and the resulting argument values are
stored in those locations. Then, the forms in the body of the lambda
expression (which may contain definitions and thus represent a letrec* form, see ) are evaluated
sequentially in the extended environment. The results of the last
expression in the body are returned as the results of the procedure
call; the last expression in the body is in tail context.
Formals must have one of the following
forms:
(variable1…)The procedure takes a fixed number of arguments; when the procedure is called, the arguments are stored in the bindings of the corresponding variables.
variableThe procedure takes any number of arguments; when the procedure is called, the sequence of arguments is converted into a newly allocated list, and the list is stored in the binding of the
variable.(variable1…variablen.variablen+1)If a period
.precedes the last variable, then the procedure takes n or more arguments, where n is the number of parameters before the period (there must be at least one). The value stored in the binding of the last variable is a newly allocated list of the arguments left over after all the other arguments have been matched up against the other parameters.
It is a syntax violation for a variable to appear more than once in formals.
Each procedure created as the result of evaluating a lambda expression receives (conceptually) a fresh location
tag, distinct from the location tags of all existing procedures.
Implementations may avoid creating a new procedure object when
evaluating a lambda expression if they can prove before
doing so that the behaviour of the resulting procedure when called
would be the same (returning the same values and having the same
side effects) as an existing procedure, for all arguments to that
procedure. In this case, the lambda expression will
evaluate to that existing procedure, which will retain the same
location tag it was given when created.
(case-lambdacase-lambda clause…)
SyntaxEach case-lambda clause must be of
the form
(formals body)Formals must be as in a lambda form.
1.2.1. Semantics
A case-lambda expression evaluates to
a procedure. This procedure, when applied, tries to match its
arguments to the case-lambda clauses in order from
left to right. The arguments match a clause if one of the following
conditions is fulfilled:
Formalshas the form(variable…)and the number of arguments is the same as the number of formal parameters informals.Formalshas the form(variable1…variablen.variablen+1)and the number of arguments is at leastn.Formalshas the formvariable.
For the leftmost clause matched by the
arguments, the variables of the formals are bound to
fresh locations containing the argument values in the same arrangement
as with lambda.
The last expression of a body in a case-lambda expression is in tail context.
The procedure returned by case-lambda is given a location tag, under the same
conditions as procedures returned by lambda.
Example
Returns #t if obj is a procedure; otherwise, returns #f.
|(procedure? car) ⇒ #t|(procedure? car) ⇒ #f|(procedure? (lambda (x) (* x x))) ⇒ #t|(procedure? (lambda (x) (* x x))) ⇒ #f
Requirementsrest-args must be a list. proc should accept n arguments,
where n is the number of args plus
the length of the list rest-args.
DescriptionThe apply procedure calls proc with the elements of the list (append (list as the actual arguments. If a call
to arg1 …) rest-args)apply occurs in a tail context, the call to proc is also in a tail context.
1.4.1. Examples
|(apply + (list 3 4)) ⇒ 71 |(define compose|(lambda (f g)|(lambda args|(f (apply g args)))))5 ||((compose sqrt *) 12 75) ⇒ 30