Clojure核心函数参数的位置似乎相当混乱。背后的逻辑是什么?

Clojure核心函数参数的位置似乎相当混乱。背后的逻辑是什么?,clojure,lisp,clojurescript,clojure-core,Clojure,Lisp,Clojurescript,Clojure Core,作为一个新的Clojurian,对于我来说,一些核心函数在参数顺序/位置上似乎有点反直觉和混乱,下面是一个例子: > (nthrest (range 10) 5) => (5 6 7 8 9) > (take-last 5 (range 10)) => (5 6 7 8 9) 也许有一些规则/逻辑在背后,我还没有看到 我不相信Clojure核心团队做出了这么多杰出的技术决策,忘记了函数命名/参数排序的一致性 还是我应该记住它的本来面目 谢谢 有点离题: rand&

作为一个新的Clojurian,对于我来说,一些核心函数在参数顺序/位置上似乎有点反直觉和混乱,下面是一个例子:

> (nthrest (range 10) 5) 
=> (5 6 7 8 9)

> (take-last 5 (range 10)) 
=> (5 6 7 8 9)
也许有一些规则/逻辑在背后,我还没有看到

我不相信Clojure核心团队做出了这么多杰出的技术决策,忘记了函数命名/参数排序的一致性

还是我应该记住它的本来面目

谢谢

有点离题:


rand&rand int VS random sample-另一个例子,函数命名似乎不一致,但这是一个很少使用的函数,所以这不是什么大问题。

对于某些函数,尤其是顺序输入、顺序输出的函数,参数是按如下顺序排列的:

(ns tst.demo.core
  (:use tupelo.core tupelo.test))

(dotest
  (let [dozen      (range 12)
        odds-1     (filterv odd? dozen)
        filter-odd (partial filterv odd?)
        odds-2     (filter-odd dozen) ]
    (is= odds-1 odds-2
      [1 3 5 7 9 11])))
对于其他函数,Clojure通常遵循最大优先顺序,或最重要优先顺序,这些函数通常具有相同的结果。因此,我们看到的例子如下:

(get <map> <key>)
(get <map> <key> <default-val>)
而且 我个人觉得,尝试使用partial和evens-1一样解析代码真的很烦人,尤其是对于用户定义函数,甚至是没有+那么简单的标准函数

如果partial与2个或更多参数一起使用,情况尤其如此

对于1-arg的情况,为evens-2看到的函数literal对我来说更可读

如果存在2个或多个参数,请将命名函数设置为本地函数(如evens-3所示),或常规定义为某些fn。。。全球功能


对于某些函数,尤其是seq-in、seq-out的函数,参数是按顺序排列的,因此可以按如下方式使用部分参数:

(ns tst.demo.core
  (:use tupelo.core tupelo.test))

(dotest
  (let [dozen      (range 12)
        odds-1     (filterv odd? dozen)
        filter-odd (partial filterv odd?)
        odds-2     (filter-odd dozen) ]
    (is= odds-1 odds-2
      [1 3 5 7 9 11])))
对于其他函数,Clojure通常遵循最大优先顺序,或最重要优先顺序,这些函数通常具有相同的结果。因此,我们看到的例子如下:

(get <map> <key>)
(get <map> <key> <default-val>)
而且 我个人觉得,尝试使用partial和evens-1一样解析代码真的很烦人,尤其是对于用户定义函数,甚至是没有+那么简单的标准函数

如果partial与2个或更多参数一起使用,情况尤其如此

对于1-arg的情况,为evens-2看到的函数literal对我来说更可读

如果存在2个或多个参数,请将命名函数设置为本地函数(如evens-3所示),或常规定义为某些fn。。。全球功能


使用seq的函数通常将实际seq作为最后一个参数。 地图、过滤器、遥控器等

访问和更改单个元素将集合作为第一个元素:conj、assoc、get、update

这样,您就可以将->>宏与集合统一使用, 以及始终如一地创建传感器


很少有人需要使用as->来更改参数顺序。如果必须这样做,您可以借此机会检查自己的函数是否遵循该约定。

使用seq的函数通常将实际seq作为最后一个参数。 地图、过滤器、遥控器等

访问和更改单个元素将集合作为第一个元素:conj、assoc、get、update

这样,您就可以将->>宏与集合统一使用, 以及始终如一地创建传感器


很少有人需要使用as->来更改参数顺序。如果您必须这样做,这可能是一个检查您自己的功能是否遵循该约定的机会。

Clojure.org上有一个关于此问题的常见问题解答:

核心函数中arg顺序的经验法则是什么? 主集合操作数排在第一位。这样就可以写作了→ 它们的位置与它们是否具有可变的算术参数无关。在OO语言和公共Lisp插槽值、aref、elt中都有这样的传统

考虑序列的一种方法是从左侧读取,从右侧馈送:


Clojure.org上有关于此问题的常见问题解答:

核心函数中arg顺序的经验法则是什么? 主集合操作数排在第一位。这样就可以写作了→ 它们的位置与它们是否具有可变的算术参数无关。在OO语言和公共Lisp插槽值、aref、elt中都有这样的传统

考虑序列的一种方法是从左侧读取,从右侧馈送:


你可以在网上找到很多关于这个主题的讨论,特别是在线程方面。例如是一个经典。你可以在网上找到很多关于这个话题的讨论,特别是在线程方面。例如这大体上是正确的,但应该注意的是,第n个函数族打破了这一规则,先取一个序列,后取一个索引。我认为这是因为它们的参数顺序是从其他Lisp中具有相同名称的函数中借用的,而Clojure还没有形成自己的风格。有人认为,N富罗
ws这个规则是因为它首先需要一个集合,比如get,而不是一个序列,但我并不真正相信这个-你可以像序列一样使用它。有人会希望你在向量上使用N,或者你会支付线性访问成本。我不认为它打破了惯例。这大体上是正确的,但应该注意的是,第n个函数族打破了这一规则,首先取一个序列,最后取一个索引。我认为这是因为它们的参数顺序是从其他Lisp中具有相同名称的函数中借用的,而Clojure还没有形成自己的风格。有人认为nth遵循这条规则,因为它首先需要一个集合,比如get,而不是序列,但我并不真正相信这一点——你可以像序列一样使用它。有人会希望你在向量上使用N,或者你会支付线性访问成本。我不认为这违反了惯例。