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