) Два примера, которые Кент Дибвиг приводит в «Язык программирования схем» для letrec и letrec *:
(letrec ([sum (lambda (x)
(if (zero? x)
0
(+ x (sum (- x 1)))))])
(sum 5))
и
(letrec* ([sum (lambda (x)
(if (zero? x)
0
(+ x (sum (- x 1)))))]
[f (lambda () (cons n n-sum))]
[n 15]
[n-sum (sum n)])
(f))
Первый также может быть записанным как именованный let:
(let sum ([x 5])
((lambda (x)
(if (zero? x)
0
(+ x (sum (- x 1))))) x))
, а второй может быть записан как let с внутренними определениями:
(let ()
(define sum (lambda (x)
(if (zero? x)
0
(+ x (sum (- x 1))))))
(define f (lambda () (cons n n-sum)))
(define n 15)
(define n-sum (sum n))
(f))
Формы letrec / letrec * не кажутся более краткими или ясными, чем именованные let или let с внутренними определениями
Может ли кто-нибудь показать мне пример, в котором letrec / letrec * действительно улучшает код или является необходимым вместо именованного let или let с внутренними определениями.