Nik*_*hev 1 lisp clojure clojurescript clojure-core
对我来说,一个新的 Clojurian,当涉及到参数顺序/位置时,一些核心函数似乎相当违反直觉和令人困惑,这是一个例子:
> (nthrest (range 10) 5)
=> (5 6 7 8 9)
> (take-last 5 (range 10))
=> (5 6 7 8 9)
Run Code Online (Sandbox Code Playgroud)
也许它背后有一些我还没有看到的规则/逻辑?
我拒绝相信 Clojure 核心团队做出了如此多出色的技术决策,却忘记了函数命名/参数排序的一致性。
还是我应该记住它的原样?
谢谢
有点题外话:
rand
& rand-int
VS random-sample
- 另一个例子,函数命名似乎不一致,但这是一个很少使用的函数,所以没什么大不了的。
Clojure.org 上有一个关于这个问题的常见问题解答:https ://clojure.org/guides/faq#arg_order
核心函数中 arg 顺序的经验法则是什么?
主要集合操作数在前。这样一个人可以写?及其同类,它们的位置与它们是否具有可变的参数无关。在 OO 语言和 Common Lisp 中有这样的传统
(slot-value, aref, elt)
。考虑序列的一种方法是从左侧读取它们并从右侧馈送它们:
Run Code Online (Sandbox Code Playgroud)<- [1 2 3 4]
大多数序列函数消耗和产生序列。因此,将其可视化的一种方法是作为一个链:
Run Code Online (Sandbox Code Playgroud)map <- filter <- [1 2 3 4]
考虑许多 seq 函数的一种方法是它们以某种方式参数化:
Run Code Online (Sandbox Code Playgroud)(map f) <- (filter pred) <- [1 2 3 4]
因此,序列函数最后获取它们的源,以及它们之前的任何其他参数,并且部分允许如上所述的直接参数化。在函数式语言和 Lisps 中有这样的传统。
请注意,这与最后取主操作数不同。一些序列函数有多个源(concat、interleave)。当序列函数是可变参数时,通常在它们的源中。
改编自Rich Hickey 的评论。
使用 seqs 的函数通常将实际的 seq 作为最后一个参数。(地图、过滤器、远程等)
访问和“更改”单个元素将集合作为第一个元素:conj、assoc、get、update
这样,您可以(->>)
一致地将宏与集合一起使用,并一致地创建转换器。
很少有人不得不求助于(as->)
改变参数顺序。如果您必须这样做,这可能是检查您自己的函数是否遵循该约定的机会。
归档时间: |
|
查看次数: |
116 次 |
最近记录: |