Во время чтения "The Seasoned Schemer" я начал узнавать о letrec
. Я понимаю, что он делает (можно дублировать с помощью Y-Combinator), но книга использует его вместо повторения на уже define
d функции, работающей на аргументах, которые остаются статическими.
Пример старой функции, использующей функцию define
d, возвращающуюся само по себе (ничего особенного):
(define (substitute new old l)
(cond
((null? l) '())
((eq? (car l) old)
(cons new (substitute new old (cdr l))))
(else
(cons (car l) (substitute new old (cdr l))))))
Теперь для примера этой же функции, но используя letrec
:
(define (substitute new old l)
(letrec
((replace
(lambda (l)
(cond
((null? l) '())
((eq? (car l) old)
(cons new (replace (cdr l))))
(else
(cons (car l) (replace (cdr l))))))))
(replace lat)))
Помимо того, что я немного длиннее и сложнее читать, я не знаю, почему они переписывают функции в книге, чтобы использовать letrec. Есть ли повышение скорости при повторении по статической переменной таким образом, потому что вы не продолжаете передавать его?
Является ли эта стандартная практика для функций с аргументами, которые остаются статическими, но один сокращаемый аргумент (например, повторяя элементы списка)?
Некоторые данные из более опытных Schemers/LISPers помогут!