Previous: baselib transformers, Up: baselib [Index]
A tail call is a procedure call that occurs in a tail context. Tail contexts are defined inductively. Note that a tail context is always determined with respect to a particular lambda expression.
(lambda ?formals ?definition* ?expression* ?tail-expression)
(if ?expression ?tail-expression ?tail-expression) (if ?expression ?tail-expression) (cond ?cond-clause+) (cond ?cond-clause* (else ?tail-sequence)) (case ?expression ?case-clause+) (case ?expression ?case-clause* (else ?tail-sequence)) (and ?expression* ?tail expression) (or ?expression* ?tail expression) (let ?bindings ?tail-body) (let ?variable ?bindings ?tail-body) (let* ?bindings ?tail-body) (letrec* ?bindings ?tail-body) (letrec ?bindings ?tail-body) (let-values ?mv-bindings ?tail-body) (let*-values ?mv-bindings ?tail-body) (let-syntax ?bindings ?tail-body) (letrec-syntax ?bindings ?tail-body) (begin ?tail-sequence)
A ?cond clause is:
(?test ?tail-sequence)
a ?case-clause is:
((?datum*) ?tail sequence)
a ?tail-body is:
?definition* ?tail-sequence
and a ?tail-sequence is:
?expression* ?tail-expression
cond
expression is in a tail context, and has a clause of
the form (?expression1 => ?expression2)
then the
(implied) call to the procedure that results from the evaluation of
?expression2 is in a tail context. ?expression2 itself is
not in a tail context.
Certain built–in procedures must also perform tail calls. The first
argument passed to apply
and to call/cc
, and the second
argument passed to call-with-values
, must be called via a tail
call.
In the following example the only tail call is the call to f
.
None of the calls to g
or h
are tail calls. The reference
to x
is in a tail context, but it is not a call and thus is not a
tail call.
(lambda () (if (g) (let ((x (h))) x) (and (g) (f))))
NOTE Implementations may recognize that some non–tail calls, such as the call to
h
above, can be evaluated as though they were tail calls. In the example above, thelet
expression could be compiled as a tail call toh
. (The possibility ofh
returning an unexpected number of values can be ignored, because in that case the effect of thelet
is explicitly unspecified and implementation–dependent.)
Previous: baselib transformers, Up: baselib [Index]