请在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 的 #() 语法可以完成柯里化无法实现的功能,尽管输入可能会更复杂一些。如果我的信息中未能提及,或者在相关讨论中未讨论到的设计权衡,我也会感到不奇怪。

+5

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

TL;DR: Clojure 被设计为提供可变参数函数,这与柯里化相互排斥。

如果你使用柯里化,你也不能使用命名(关键字)参数。

TIL 关于 Clojure 中的关键字参数
+3

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

现在 Clojure 的核心库中并没有 appl 函数。我未知它的历史,直到我在旧 Google 群组信息中进行关键字搜索时才知道它。

这篇帖子也讨论了为什么+不能像可变参数一样柯里化

(+) ;=> 0
(+ n) ;=> n -- 并不意味着“增加n”
(+ 1 2 3 4) ;=> 10

编辑
我觉得这样做是有道理的!由于支持可变参数和关键字参数,所以不能有自动柯里化。

然而,你可以编写一个接受变元性和具有该功能的函数的arity的柯里化函数。或者,已经提出了各种宏。不过,引入这种行为可能会让一些人感到困惑。感谢您的洞察!
+1

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

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

...