制作亚历山大港是不是很愚蠢:咖喱不一定使用funcall?

时间:2017-08-24 13:01:44

标签: common-lisp currying lisp-2

目前必须使用curry调用与亚历山大的funcall相关的函数。但是,可以设置新函数symbol-function,这样我们就可以在没有它的情况下将其视为真实函数。在https://lispcookbook.github.io/cl-cookbook/functions.html#with-the-alexandria-library上有说明:

(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)

是否有充分理由不允许这两种风格?在这个currying的背景下,这看起来很有趣。

ps:3周前我确实询问过Alexandria的问题跟踪器

pps:https://gitlab.common-lisp.net/alexandria/alexandria/blob/master/functions.lisp#L116

2 个答案:

答案 0 :(得分:3)

根据您的评论,并查看the issue,是的,这将是"愚蠢的"更改curry以便它绑定全局命名空间中的函数:

  • 这将是curry的重大更改,这会破坏现有代码
  • 据我所知,具有此功能的宏与Alexandria的精神无法很好地融合。这更适合Serapeum,恰好已经定义了这样一个函数,即defalias。如您所见,定义比使用symbol-value更复杂一些。另请参阅documentation

答案 1 :(得分:0)

作为参考,这个简单的宏完成了这项工作:

(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))