schemeracketletletrec

Meaning of letrec in Scheme/Racket


So as far as I understand, the following: let, let*, letrec and letrec* are synthetics sugars used in Scheme/Racket.

Now, if I have a simple program:

(let ((x 1)
      (y 2))
     (+ x y))

It is translated into:

((lambda (x y) (+ x y)) 1 2)

If I have:

(let* ((x 1)
      (y 2))
     (+ x y))

It is translated into:

((lambda (x) ((lambda (y) (+ x y))) 2) 1)

Now, for my first question, I understand the meaning of a letrec expression, which enables one to use recursion inside a let, but I do not understand how exactly it is done. What is letrec translated to?

For example, what will

(letrec ((x 1)
      (y 2))
     (+ x y)) 

be translated into?

The second question is similar about letrec* - But for letrec* I do not understand how exactly it differs from letrec? And also, what will a letrec* expression be translated into?


Solution

  • See the paper "Fixing Letrec: A Faithful Yet Efficient Implementation of Scheme’s Recursive Binding Construct" by Oscar Waddell, Dipanwita Sarkar, and, R. Kent Dybvig.

    The paper starts with a simple version and proceeds to explain a more sophisticated expansion:

    https://www.cs.indiana.edu/~dyb/pubs/fixing-letrec.pdf