What's the difference between R6RS's `letrec`, `letrec*` and Racket's `letrec`?

837 views Asked by At

Both letrec and letrec* are in R6RS, but there's only letrec in Racket, no letrec*. What are the differences between these?

1

There are 1 answers

2
soegaard On BEST ANSWER

In short Racket letrec and R6RS letrec* is the same. The evaluation order is specified for these. In R5RS letrec the order is unspecified.

Since the order of R5RS letrec is unspecified implementation can choose a fixed order (for example left to right) or they can let the compiler choose different orders for each use (in order to get faster code).

From the Racket documentation.

R5RS letrec:

Semantics: The < variable>s are bound to fresh locations holding undefined values, the < init>s are evaluated in the resulting environment (in some unspecified order), each < variable> is assigned to the result of the corresponding < init>, the < body> is evaluated in the resulting environment, and the value(s) of the last expression in < body> is(are) returned. Each binding of a < variable> has the entire letrec expression as its region, making it possible to define mutually recursive procedures.

Racket letrec:

Like let, including left-to-right evaluation of the val-exprs, but the locations for all ids are created first and filled with #< undefined>, all ids are bound in all val-exprs as well as the bodys, and each id is set immediately after the corresponding val-expr is evaluated. The ids must be distinct according to bound-identifier=?.

R6RS letrec*:

Semantics: The < variable>s are bound to fresh locations, each < variable> is assigned in left-to-right order to the result of evaluating the corresponding < init>, the < body> is evaluated in the resulting environment, and the values of the last expression in < body> are returned. Despite the left-to-right evaluation and assignment order, each binding of a < variable> has the entire letrec* expression as its region, making it possible to define mutually recursive procedures.