2

重複の可能性:
clojure のベクトル関数の定義が非常に冗長なのはなぜですか?

私の質問を明確にするために、 の定義をlist*例に取りましょう。

(defn list*
  "Creates a new list containing the items prepended to the rest, the
  last of which will be treated as a sequence."
  {:added "1.0"
   :static true}
  ([args] (seq args))
  ([a args] (cons a args))
  ([a b args] (cons a (cons b args)))
  ([a b c args] (cons a (cons b (cons c args))))
  ([a b c d & more]
    (cons a (cons b (cons c (cons d (spread more)))))))

list*私の質問は、次のように定義しない理由です。

(defn list*
  "Creates a new list containing the items prepended to the rest, the
  last of which will be treated as a sequence."
  {:added "1.0"
   :static true}
  ([args] (seq args))
  ([a & more] (cons a (spread more))))
4

1 に答える 1

5

主な理由はパフォーマンスです。

小さなアリティを持ついくつかの追加バージョンを明示的に提供すると、Clojure コンパイラがより最適化されたコードを作成するのに役立ちます (特に、小さなアリティのケースが最も一般的に使用されるため)。

これは、オーバーロードされたバージョンが可変長引数リストを処理する必要がない場合 (& more) に特に当てはまります。これは、可変長引数リストを処理すると、通常の位置パラメーターよりも多くのオーバーヘッドが発生するためです。

于 2012-08-10T09:10:31.270 に答える