Глупо ли делать александрию: карри не обязательно использует funcall?
В настоящее время функция карри с Александрией curry
должен быть вызван с funcall
, Однако можно установить новую функцию symbol-function
так что мы можем обойтись без него и относиться к нему как к реальной функции. Иллюстрировано на https://lispcookbook.github.io/cl-cookbook/functions.html:
(defun adder (foo bar)
"Add the two arguments."
(+ foo bar))
(defvar add-one (alexandria:curry #'adder 1) "Add 1 to the argument.")
(funcall add-one 10) ;; => 11
(setf (symbol-function 'add-one) add-one)
(add-one 10) ;; => 11
;; and still ok with (funcall add-one 10)
Есть ли веская причина не допустить оба стиля? Это выглядит довольно интересно для меня в этом контексте карри.
PS: я спрашивал о трекере Александрии около 3 недель назад
pps: https://gitlab.common-lisp.net/alexandria/alexandria/blob/master/functions.lisp#L116
2 ответа
Исходя из вашего комментария и глядя на проблему, да, было бы "глупо" менять curry
так что он связывает функции в глобальном пространстве имен:
- Это было бы серьезным изменением для
curry
, который сломал бы существующий код - Насколько мне известно, макрос с такой функциональностью не совсем соответствует духу Александрии. Это было бы лучше подходит для Serapeum, который уже определил такую функцию, а именно
defalias
, Как видите, определение немного сложнее, чем использованиеsymbol-value
, Смотрите также документацию.
Для справки, этот простой макрос выполняет свою работу:
(defmacro defcurry (name function &rest arguments)
"Returns a regular function, created by currying FUNCTION with ARGUMENTS."
`(let ((closure (alexandria:curry ,function ,@arguments)))
(setf (symbol-function ,name) closure)))
Пример:
(defun adder (x y) (+ x y))
(defcurry 'add2 #'adder 2)
(add2 3) ;; no "funcall" here
;; => 5"
редактировать: но... это гораздо проще:
(defun add2 (a)
(adder 2 a))