Chapter 4Foundational library

Note

This chapter will be extended by a future fascicle.

1Procedures

(lambda formals body)

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.

variable

The 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.

(variable1variablen . 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-lambda case-lambda clause)

SyntaxEach case-lambda clause must be of the form

(formals body)
Formals must be as in a lambda form.

1.2.1Semantics

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:

  • Formals has the form (variable) and the number of arguments is the same as the number of formal parameters in formals.

  • Formals has the form (variable1variablen . variablen+1) and the number of arguments is at least n.

  • Formals has the form variable.

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

procedure?(obj);
obj;

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
apply(proc, arg1, rest-args);
proc;
arg1 …;
rest-args;

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 arg1 …) rest-args) as the actual arguments. If a call to apply occurs in a tail context, the call to proc is also in a tail context.

1.4.1Examples

  |(apply + (list 3 4)) ⇒ 7
1 |(define compose
  |  (lambda (f g)
  |    (lambda args
  |      (f (apply g args)))))
5 | 
  |((compose sqrt *) 12 75) ⇒ 30