Попытка его в MIT Scheme работает
(define ((K x) y) x)
;Value: k
((k 3) 4)
;Value: 3
По-видимому, эти определения для K
и S
комбинаторов из combinatorial logicSKI calculus.
Мы можем определить ту же функцию в явном виде,
(define k (lambda (x) (lambda (y) x)))
;Value: k
((k 3) 4)
;Value: 3
Видимо, MIT-схема делает это для нас, так же, как и в случае обычных определений, как (define (fun foo) bar)
переводится на (define fun (lambda (foo) bar))
.
S
комбинатора будет определен явно как
(define S (lambda (x) (lambda (y) (lambda (z)
((x z) (y z))))))
(define ((add a) b) (+ a b))
;Value: add
(define (add1 a) (+ a 1))
;Value: add1
(((s add) add1) 3)
;Value: 7
Это, как currying языков (например, как Haskell) работа, где каждая функция является функцией одного аргумента. Haskell очень близко к комбинаторной логике в этом отношении, есть нет скобок используются, и мы можем написать то же определение, просто как
_K x y = x
_S x y z = x z (y z)
Так что _S (+) (1+) 3
производит 7
.
Спасибо. Теперь я вижу raison d'etre синтаксиса определения функции Scheme, поэтому его можно извлечь рекурсивно. – Jiaji
@Jiaji, возможно, вы не хотите зависеть от такого поведения. Я никогда раньше этого не видел. Это может быть не стандартное (но, может быть, и так). Он также работает в r5rs Dr.Racket. Стандарт R5RS в разделе [5.2 Определения] (http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-ZH-8.html#%_sec_5.2) дает только '(define .. .) 'и' (define (variable ...) ...) ', поэтому я не уверен, что это вообще законно. Тем не менее, я могу видеть, где компилятор, который преобразует '(define (. Args) body)' in '(define (тело лямбда-args))' и продолжает применять преобразование @Jiaji –
@, в результате получится соответствующее определение. Возможно, более поздние версии Scheme _do_ определяют это как синтаксическое преобразование, но я думаю, что это не является технически законным в R5RS, поскольку спецификация допускает только формы с переменной: '(define ...)' и '(define (. ..) ...) '. –