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?
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: