Неявное карри в схеме с синтаксическими правилами?
-
04-10-2019 - |
Вопрос
У Джеффри Meunier есть неявный макрос карри здесь, который использует Defmacro. Мне было интересно, если кто-то когда-нибудь написал это с помощью синтаксических правил?
Решение
Существует ряд реализаций карри для схемы - никто не может быть так же элегантным, как haskell, поскольку там функции всегда используются анарии. (Но, конечно, это может быть реализовано в достаточно мощной схеме, как Ракетка.)
Что касается макроса, который вы выкопали - это довольно плохой: он не только использует негигиенический макрос, он также звонит eval
явно и опирается на реализацию окружающей среды и т. Д. Но легко сделать это с простой syntax-rules
макрос AFAICT, это то, что он реализует:
(define-syntax-rule (clambda (x ... . r) b ...)
(let ([len (length '(x ...))] [real (lambda (x ... . r) b ...)])
(let loop ([argss '()] [n 0])
(lambda args
(let ([n (+ n (length args))] [argss (cons args argss)])
(if (>= n len)
(apply real (apply append (reverse argss)))
(loop argss n)))))))
Но здесь есть важное замечание. Страница, которую вы ссылаетесь, говорите, что проблема функциональной версии состоит в том, что она явная - но она также имеет важное преимущество: с реализацией макроса необходимо определить функцию, используя clambda
, тогда как функциональная версия может использоваться с любым встроенным функциями. Во многих реализациях схемы существуют объекты для проверки артерии функции, и используя это можно реализовать версию функции Carrying, которая знает, когда вызовите оригинальную функцию.