您的位置:首页 > 其它

June 5th Friday (六月 五日 金曜日)

2009-06-26 20:45 429 查看
Quasiquote forms may be nested. Substitutions are made only for unquoted components appearing at the same nesting level as
the outer most quasiquote. The nesting level (quasiquote qq template) syntax increases by one inside each successive quasiquotation,
and unquote auxiliary syntax decreases by one inside each unquotation.

`(a`(b ,(+ 1 2) ,(foo ,(+,1 3) d) e) f)
=> (a `(b ,(+ 1 2) ,(foo 4 d) e) f)

More formally, an input form F matches a pattern P if and only if one of the following holds:

*P is an underscore ( _ ).
*P is a pattern variable.
*P is a literal identifier and F is an identifier such that both P and F would refer to the same binding if both were to appear in
the output of the macro outside of any bindings inserted into the output of the macro. (If neither of two like-named identifiers refers
to any binding, i.e., both are undefined, they are considered to refer to the same binding.)
*P is of the form (P1 ... Pn) and F is a list of n elements that match P1 through Pn.
*P is of the form (P1 ... Pn . Px) and F is a list or improper list of n or more elements whose first n elements match P1 through Pn and
whose nth cdr matches Px.
*P is of the form (P1 ... Pk Pe <ellipsis> Pm+1 ... Pn), where <ellipsis> is the identifier ... and F is a list of n elements whose first
k elements match P1 through Pk, whose next m - k elements each match Pe, and whose remaining n - m elements match Pm+1 through Pn.
*P is of the form (P1 ... Pk Pe <ellipsis> Pm+1 ... Pn . Px), where <ellipsis> is the identifier ... and F is a list or improper list of
n elements whose first k elements match P1 through Pk, whose next m - k elements each match Pe, whose next n - m elements match Pm+1 through
Pn, and whose nth and final cdr matches Px.
*P is of the form #(P1 ... Pn) and F is a vector of n elements that match P1 through Pn.
*P is of the form #(P1 ... Pk Pe <ellipsis> Pm+1 ... Pn), where <ellipsis> is the identifier ... and F is a vector of n or more elements
whose first k elements match P1 through Pk, whose next m - k elements each match Pe, and whose remaining n - m elements match Pm+1 through Pn.
*P is a pattern datum (any nonlist, nonvector, nonsymbol datum) and F is equal to P in the sense of the equal? procedure.

When a macro use is transcribed according to the template of the matching <syntax rule>, pattern variables that occur in the template are
replaced by the subforms they match in the input.

Tail call

A tail callis 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.

The last expression within the body of a lambda expression, shown as <tail expression> below, occurs in a tail context.

(lambda <formals>
<definition>*
<expression>* <tail expression>)

If one of the following expressions is in a tail context, then the subexpressions shown as <tail expression> are in a tail context. These were derived
from specifications of the syntax of the forms described in this chapter by replacing some occurrences of <expression> with <tail expression>. Only those
rules that contain tail contexts are shown here.

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

If a 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-with-current-continuation, 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,
the let expression could be compiled as a tail call to h. (The possibility of h returning an unexpected number of values can be ignored, because in that case the
effect of the let is explicitly unspecified and implementation-dependent.)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: