Глупо ли делать александрию: карри не обязательно использует 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))
Другие вопросы по тегам