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 一定了解柯里化,这一点无可置疑。但对其重视程度,我并不清楚。匿名函数和 Clojure 的 #() 语法可以进行柯里化无法做到的事情,尽管这样做可能需要输入更多的字符。如果我的信息中没有提及,并在链接的讨论帖中没有涉及到的其他设计权衡方案,我并不会感到惊讶。

+5
by

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

TL;DR: Clojure 设计时考虑到变长函数,这与柯里化是互相排斥的。

如果采用柯里化,你也无法拥有命名(关键字)参数。

by
我刚刚了解了 Clojure 中的关键字参数。
+3
by

另一个包含 Rich Hickey 关于柯里化的旧讨论贴,以及一个进行部分应用的函数 appl(我想“appl”这个名字本身就是一个笑话,因为它只占“application”这个词的一部分):https://groups.google.com/forum/#!searchin/clojure/currying$20hickey|sort:date/clojure/TjvA5AQArUs/9bN78s4w-VkJ

在现在的 Clojure 核心中没有名为 “appl” 的函数。我不知道它的历史,而且直到通过旧的 Google 群组消息进行关键字搜索之前,我并不知道它的存在。

by
该帖子还说明了为什么加号(+)也无法像变长函数一样进行柯里化。

(+) ;=> 0
(+ n) ;=> n -- 并不代表 "加 n"
(+ 1 2 3 4) ;=> 10
我发现这样是有道理的!由于支持可变参数和关键字参数,因此不可能实现自动柯里化。

然而,您可以编写一个接受参数数量和函数的柯里化函数。或者,还提出了各种宏。尽管如此,引入这种行为可能会让人感到困惑。感谢您的见解!
+1

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

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

...