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显然 knew about 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”这个词的玩笑,因为它仅仅是“application”这个词的一部分):https://groups.google.com/forum/#!searchin/clojure/currying$20hickey|sort:date/clojure/TjvA5AQArUs/9bN78s4w-VkJ

现在的Clojure core中不存在appl函数。我不了解它的历史,直到我在旧的谷歌群组消息中进行关键字搜索时才知道它。

这篇帖子也讨论了为什么+不能像可变参数一样进行currying

(+) ;=> 0
(+ n) ;=> n -- 这不代表“添加n”
(+ 1 2 3 4) ;=> 10

编辑了
我觉得这个解释很有道理!因为Clojure支持可变参数和关键字参数,所以不能使用自动柯里化。

然而,你可以编写一个柯里化函数,该函数接收一个参数个数和满足这种方式的工作函数。或者,也有人提出了各种宏。尽管,引入这种行为可能会让人们感到困惑。感谢你的见解!
+1

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

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

...