7

ベクトルの実装が非常に冗長である理由を知りたいのですが。それがただできない理由は何ですか[][a]そして[a & args]

これが私が得たものclj-1.4.0です。

=> (source vector)
(defn vector
  "Creates a new vector containing the args."
  {:added "1.0"
   :static true}
  ([] [])
  ([a] [a])
  ([a b] [a b])
  ([a b c] [a b c])
  ([a b c d] [a b c d])
  ([a b c d & args]
     (. clojure.lang.LazilyPersistentVector (create (cons a (cons b (cons c (cons d args))))))))
nil
4

2 に答える 2

10

最初のいくつかのケースには、最も一般的に呼び出されるため、高速化するための直接呼び出しがあります。多くの引数で呼び出されるまれなケースでは、より多くの呼び出しが必要になるため、より多くの時間が必要になる場合がありますが、これにより一般的なケースが簡潔に保たれます。これは、意図的な速度と冗長性のトレードオフでした。また、引数リストを見て関数の使用法を明確にし、人々の IDE を多数のアリティのリストで混乱させることもありません。

Clojure のコア関数のほとんどは、同様の署名を持っています。

于 2012-07-19T23:40:48.703 に答える
0

@ArthurUlfeldtのソリューションにさらに。

namespace など、コア関数の参照実装を持つ場合がありますclojure.core.reference。これらは、標準の対応するものよりも遅くなりますが、短くなるため、より明確になります。テスト体制は、それらが同じ結果を生み出すことを確認します。

たとえば、の参照実装は次のvectorようになります。

(ns clojure.core.reference)

(defn vector
  "Creates a new vector containing the args."
  {:added "1.0"
   :static true}
  [& args]
  (. clojure.lang.LazilyPersistentVector (create args)))

コア ライブラリで採用されているさまざまな最適化と高速化をテストすることに加えて、リファレンス実装は、コードが何をするかを理解しようとする人々にとって最初の寄港地となるでしょう。

于 2014-07-04T08:06:03.573 に答える