欢迎!请参阅 关于 页面获取更多关于如何使用本站的信息。
今天我突然想到一个问题:Clojure 的设计和实现过程中,是否曾考虑过自动柯里化的可能性?
假设你编写了这样的函数:
(defn add [x y] (+ x y))
(map (add 2) [1 2 3 4 5])
如果 Clojure 允许自动柯里化,那么将会得到 [3 4 5 6 7],但当前的实现会因为参数数量不匹配而报错。在我看来,这样的行为比错误更有效率。所以我想知道,如果曾经考虑过这种特性,为什么会有意避免它。
[3 4 5 6 7]
我不了解这个问题的完整答案,但是以下是一个链接,它指向 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做不到的事情,尽管可能需要多几个字符。如果我的信息中没有提到许多设计上的权衡,而且这些也没有在链接的讨论线程中被提出,我并不感到惊讶。
#()
https://stackoverflow.com/questions/31373507/rich-hickeys-reason-for-not-auto-currying-clojure-functions
TL;DR:Clojure被设计为具有可变参数函数,而这与Currying是互斥的。
如果您采用Currying,您也无法拥有命名的(关键字)参数。
另一个关于Rich Hickey和Currying的老讨论线程,以及一个进行部分应用的函数appl(我猜“appl”这个名字有一点玩笑意味,因为它只是“application”这个词的部分):https://groups.google.com/forum/#!searchin/clojure/currying%20hickey|sort:date/clojure/TjvA5AQArUs/9bN78s4w-VkJ
appl
今天的Clojure核心中不存在名为“appl”的函数。我不知道它的历史,直到在旧谷歌群组消息中进行关键字搜索时才意识到。
如果您不介意使用外部库,Clojure 可以实现柯里化
https://dragan.rocks/articles/18/Fluokitten-080-Fast-function-currying-in-Clojure