2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!请参阅 关于 页面获取更多关于如何使用本站的信息。

+1 表扬
语法和读取器

今天我突然想到一个问题:Clojure 的设计和实现过程中,是否曾考虑过自动柯里化的可能性?

假设你编写了这样的函数:

(defn add [x y] (+ x y))

(map (add 2) [1 2 3 4 5])

如果 Clojure 允许自动柯里化,那么将会得到 [3 4 5 6 7],但当前的实现会因为参数数量不匹配而报错。在我看来,这样的行为比错误更有效率。所以我想知道,如果曾经考虑过这种特性,为什么会有意避免它。

4 个答案

+4 表扬

被选中
 
最佳回答

我不了解这个问题的完整答案,但是以下是一个链接,它指向 2008 年 10 月 Clojure Google 群组上的一次讨论,Rich Hickey 对一个关于如何向 Clojure 添加柯里化功能的建议进行了回应。

https://groups.google.com/forum/#!searchin/clojure/currying$20hickey|sort:date/clojure/Nsd-7Iagkws/0sVdoJl7bFgJ

Rich对Currying比较了解。但不知其被重视的程度。匿名函数和Clojure的#()语法能做Currying做不到的事情,尽管可能需要多几个字符。如果我的信息中没有提到许多设计上的权衡,而且这些也没有在链接的讨论线程中被提出,我并不感到惊讶。

+5

https://stackoverflow.com/questions/31373507/rich-hickeys-reason-for-not-auto-currying-clojure-functions

TL;DR:Clojure被设计为具有可变参数函数,而这与Currying是互斥的。

如果您采用Currying,您也无法拥有命名的(关键字)参数。

我学到了Clojure中的关键字参数
+3

另一个关于Rich Hickey和Currying的老讨论线程,以及一个进行部分应用的函数appl(我猜“appl”这个名字有一点玩笑意味,因为它只是“application”这个词的部分):https://groups.google.com/forum/#!searchin/clojure/currying%20hickey|sort:date/clojure/TjvA5AQArUs/9bN78s4w-VkJ

今天的Clojure核心中不存在名为“appl”的函数。我不知道它的历史,直到在旧谷歌群组消息中进行关键字搜索时才意识到。

那篇帖子还谈到了为什么+不能既Currying又可变参数

(+) ;=> 0
(+ n) ;=> n -- 并不代表“加n”
(+ 1 2 3 4) ;=> 10
by
编辑 by
我看这个解释是有道理的!既然支持可变参数和关键字参数,那么不可能有自动柯里化。

然而,你可以编写一个函数来处理柯里化,该函数接受一个参数个数和一个函数。另外,也提出了各种宏的建议。尽管如此,引入这种行为可能会让人感到困惑。感谢你的见解!
+1 表扬
by

如果您不介意使用外部库,Clojure 可以实现柯里化

https://dragan.rocks/articles/18/Fluokitten-080-Fast-function-currying-in-Clojure

...