简而言之,Racket的letrec和R6RS的letrec*是相同的。这些都有指定的求值顺序。在R5RS的letrec中,顺序是未指定的。由于R5RS letrec的顺序是未指定的,实现可以选择一个固定的顺序(例如从左到右),或者他们可以让编译器为每个用途选择不同的顺序(以获得更快的代码)。引用自Racket文档。 R5RS letrec:语义:< variable>将绑定到保持未定义值的新位置,< init>将在结果环境中计算(以某种未指定的顺序),每个< variable>被分配给对应的< init>的结果,< body>在结果环境中计算,并返回最后一个表达式的值。每个< variable>的绑定都具有整个letrec表达式作为其区域,因此可以定义互相递归的过程。 Racket letrec:与let相似,包括val-exprs的从左到右的求值,但是所有id的位置首先被创建并填充为#< undefined>,所有id在所有val-exprs以及bodys中都被绑定,并且每个id在相应的val-expr计算后立即设置。根据bound-identifier =?,ids必须不同。 R6RS letrec*:语义:< variable>将绑定到新位置,每个< variable>按从左到右的顺序分配给计算相应< init>的结果,< body>在结果环境中计算,并返回< body>中最后一个表达式的值。尽管存在从左到右的评估和分配顺序,但是每个< variable>的绑定都具有整个letrec*表达式作为其区域,因此可以定义互相递归的过程。