2017-08-24 44 views
0

目前与亚历山大的curry咖喱功能必须调用funcall。但是,可以设置新功能的symbol-function,这样我们就可以在没有它的情况下将其视为真正的功能。画报上https://lispcookbook.github.io/cl-cookbook/functions.html#with-the-alexandria-library做亚历山大是否愚蠢:咖哩不一定要用funcall?

(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个星期前

PPS:基于您的评论https://gitlab.common-lisp.net/alexandria/alexandria/blob/master/functions.lisp#L116

+0

护理解释downvote? – Ehvince

+1

为什么这个问题特别针对'alexandria:curry'?它只返回一个闭包,并不影响你对结果做什么。是否应该使用'(setf symbol-function)'来定义全局函数?或者你是否想要更改'alexandria:curry',以便它改变一个附加符号参数的全局绑定? – coredump

+1

“它只返回一个闭包,并不影响你对结果做什么”:这可能是我的答案。是的,我想知道为什么亚历山大,在这个currying调用没有funcall *的函数的环境中似乎是合乎逻辑的方式,并没有设置它返回的绑定。但是因为它只返回一个闭包,所以我明白了。现在,我想知道为什么没有这样做的功能,但这是另一点。谢谢 ! – Ehvince

回答

3

,看着the issue,是这将是“愚蠢的”,以改变curry使它结合功能在全局命名空间:

  • 这将是curry一个重大的变化,这将打破现有的代码
  • 宏据我所知,这个功能与Alexandria的精神不搭配。这将更适合于Serapeum,这恰好已经定义了这样的功能,即defalias。正如你所看到的,这个定义比使用symbol-value要多一点。另见documentation
+1

非常有见地,并且很好的发现了Serapeum。谢谢 ! – Ehvince

+1

我很高兴找到一个'defalias',用它代替一些代码。 – Ehvince

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