Я изучал, как языки, запрещающие использование-до-def и не имеющие изменяемых ячеек (нет set!
или setq
), тем не менее могут обеспечить рекурсию. Я, конечно, побежал через Y Combinator и друзей, например, (известный печально?):Двухслойный комбинатор "Y-style". Это распространено? Имеет ли это официальное название?
- http://www.ece.uc.edu/~franco/C511/html/Scheme/ycomb.html
- http://okmij.org/ftp/Computation/fixed-point-combinators.html
- http://www.angelfire.com/tx4/cus/combinator/birds.html
- http://en.wikipedia.org/wiki/Fixed-point_combinator
Когда я пошел к реализации " letrec "в этом стиле (т. е. разрешить локальную переменную так, чтобы она могла быть рекурсивной функцией, где под обложками она никогда не ссылается для своего собственного имени), комбинатор я в конечном итоге написание выглядит следующим образом:
Y_letrec = λf . (λx.x x) (λs . (λa . (f ((λx.x x) s)) a))
Или факторизации по U комбинатора:
U = λx.x x
Y_letrec = λf . U (λs . (λa . (f (U s)) a))
Читать это как: Y_letrec это функция, которая принимает к -be-recursed function f
. f
должна быть функцией с одним аргументом, которая принимает s
, где s
- это функция , которую f
может позвонить для достижения саморекурсии. Ожидается, что f
определит и возвращает «внутреннюю» функцию, которая выполняет «настоящую» операцию. Эта внутренняя функция принимает аргумент a
(или в общем случае список аргументов, но не может быть выражен в традиционных обозначениях). Результат вызова Y_letrec является результатом вызова f
, и предполагается, что он является «внутренней» функцией, готовой к вызову.
Причины я установил вещи таким образом, так что я мог бы использовать дерево разбора вид функции к-быть-Рекурсия непосредственно, без изменений, просто обернув дополнительный функцию слоя вокруг него в процессе преобразования при обработке letrec , Например, если оригинальный код:
(letrec ((foo (lambda (a) (foo (cdr a))))))
затем преобразованная форма была бы вдоль линий:
(define foo (Y_letrec (lambda (foo) (lambda (a) (foo (cdr a))))))
Обратите внимание, что внутренний корпус функция идентична между ними.
Мои вопросы:
- Является ли моя функция Y_letrec обычно используется?
- У этого есть хорошо устоявшееся имя?
Примечание: Первая ссылка выше относится к аналогичной функции (в «шаге 5») как «комбинаторный комбинатор Y», хотя у меня возникли проблемы с поиском авторитетного источника для этого наименования.
UPDATE 28-апреля-2013:
я понял, что Y_letrec, как определено выше, очень близко к но не идентична Z комбинатора, как это определено в Википедии. По Википедии, комбинатор Z и «комбинатор Y по-разному» - это одно и то же, и похоже, что это действительно то, что чаще всего называют «комбинатором Y-аппликативного порядка».
Итак, у меня выше нет так же, как и комбинатор Y-аппликативного порядка, как обычно написано, но почти наверняка есть смысл, в котором они связаны. Вот как я сделал сравнение:
Начиная с:
Y_letrec = λf . (λx.x x) (λs . (λa . (f ((λx.x x) s)) a))
Применить внутреннюю U:
Y_letrec = λf . (λx.x x) (λs . (λa . (f (s s)) a))
Применение внешней U:
Y_letrec = λf . (λs . (λa . (f (s s)) a)) (λs . (λa . (f (s s)) a))
Rename, чтобы соответствовать определению Википедии комбинатора Z:
Y_letrec = λf . (λx . (λv . (f (x x)) v)) (λx . (λv . (f (x x)) v))
Сравните это с Википедии Z комбинатора:
Z = λf . (λx . f (λv . ((x x) v))) (λx . f (λv . ((x x) v)))
Характерный разница в том, где функция f
прикладывается. Это имеет значение? Являются ли эти две функции эквивалентными, несмотря на эту разницу?
Как я помню, прикладной порядок соответствует нормальному порядку. В языках прикладного порядка, таких как аргументы схемы, оцениваются сразу, прежде чем функция увидит их. Это затрудняет определение Y-комбинатора. В обычном порядке, как и в традиционном лямбда-исчислении, параметры передаются и оцениваются только тогда, когда нет другого варианта. Y-комбинаторы проще в обычном порядке, например. [Хиндли и Селдин] (http://www.amazon.com/Lambda-Calculus-Combinators-Introduction-Roger-Hindley/dp/0521898854/ref=sr_1_3?ie=UTF8&qid=1367127702&sr=8-3&keywords=lambda+calculus) п. 34. – Mars