ClojureScript

1.10.516 リリース

2019年1月31日
ClojureScript チーム

注目すべき変更点

Spec instrumentation (cljs.spec.test.alpha/instrument および関連機能) は、test.check を必要としなくなりました。 cljs.spec.test.alpha/check を使用する場合は、test.check のデータ生成機能が必要になります。その場合は、clojure.test.checkclojure.test.check.properties 名前空間を require する必要があります。

Spec での test.check の使用に関する cljs.spec.test.alpha/check API で使用されるキーワードは、Clojure と一致するように clojure.spec.test.check で修飾されるようになりました。 clojure.test.check で修飾する以前の方法は引き続きサポートされています。

Clojure 1.10 の機能

例外メッセージと出力の改善

Clojure 1.10 で追加された改善された例外基盤は、このリリースで ClojureScript に移植されました。

メタデータによるプロトコル

メタデータによってプロトコルを追加する機能 (:extend-via-metadata true ディレクティブで定義されたプロトコルの場合) は、このリリースで ClojureScript に移植されました。

Datafy と Nav

clojure.datafy 名前空間は、clojure.core.protocols 名前空間の関連プロトコルとともに、ClojureScript に移植されました。

clojure.edn 名前空間

このリリースでは、cljs.reader に機能を委任する新しい clojure.edn 名前空間が追加されました。これにより、clojure.edn/readclojure.edn/read-string を使用するポータブルな Clojure / ClojureScript ソースの記述が容易になります。

型推論の改善

述語による型推論

型推論アルゴリズムは、条件式で使用されるローカルの型を推論する際に、コア述語を考慮するようになりました。

例えば、

(if (string? x)
  (inc x)
  10)

xstring? を満たすため、then ブランチでは文字列型として推論されます (そのため、inc が適用されているため警告が出力されます)。

condwhenif の上に構築されたマクロであるため、述語による推論は condwhen を含む式でも期待どおりに機能します。

コア述語に加えて、述語による型推論は instance? チェックでも機能します。したがって、たとえば (instance? Atom x) をテストすると、xcljs.core/Atom 型として推論されます。

Truthy による推論

値が nil になる可能性がある場合 (型タグではシンボル clj-nil で表される)、そのような値を参照する単純なシンボルが条件のテストとして使用されると、型推論アルゴリズムは then ブランチでは値が nil になることはないと推論します。

これは、例を用いて説明するのがおそらく最善です。次の関数があるとします

(defn f [x]
  (when (even? x)
    (inc x)))

この関数の戻り値の型は #{number clj-nil} で、数値または nil が返されることを意味します。

f を使用し、以前は #{number clj-nil} を返すものとして推論されていた次の関数は、 अब `number` を返すものとして推論されます.

(defn g [y]
  (let [z (f y)]
    (if z
      z
      17)))

実際、or マクロの展開方法により、式 (or (f 1) 17) は単に number として推論されるようになりました。

loop / recur 推論の改善

型推論アルゴリズムは、loop ローカル型を推論する際に recur パラメーター型を考慮するようになりました。

例えば、

(loop [x "a"]
  (if (= "a" x)
   (recur 1)
   (+ 3 x)))

ローカル x は以前は文字列型として推論されていました (そして、これはそれを 3 に加算する式に対して警告が出力される原因となっていました). 今では、コンパイラは x を文字列または数値のいずれかとして推論します (そのため、警告は表示されなくなります)。

多重アリティ関数と可変長引数関数の戻り値の型推論

ClojureScript 1.10.439 では関数の戻り値の型推論が追加されましたが、この機能は単一アリティ関数に対してのみ機能しました。このリリースでは、この機能が多重アリティ関数と可変長引数関数に拡張されます.

さらに、異なるアリティが異なる型を返す場合、推論される戻り値の型は適切に変化します。例えば、

(defn foo
  ([x] 1)
  ([x y] "a"))

(foo true) は数値型として推論され、(foo :a :b) は文字列型として推論されます。

Spec の改善

このリリースには、Spec 実装のいくつかの改善が含まれており、標準コアライブラリで関数を spec すること、およびコードベース内の多数の関数が spec を持つ場合の instrumentation パフォーマンスを向上させることが容易になります.

パフォーマンスの向上

範囲に対する Chunked-Seq のサポート

ClojureScript は、範囲に対して chunked-seqs をサポートするようになりました。この機能がパフォーマンスを向上させる例は次のとおりです.

(reduce + (map inc (map inc (range (* 1024 1024)))))

これは、V8 では 5 倍、SpiderMonkey では 7 倍、JavaScriptCore では 2 倍高速に評価されます.

re-seq パフォーマンスの向上

re-seq のパフォーマンスが向上し、主要な JavaScript エンジンで 1.5 倍以上の高速化が実現しました.

文字列式連結の最適化

一般に、str 関数に提供される引数は、連結される前に文字列に強制されます。このリリースでは、文字列型であると推論される引数に対して不要な強制が排除され、よりコンパクトなコード生成と速度の向上が実現します.

例えば、

(defn foo [x y]
  (str (+ x y)))

(str (name :foo/bar) "-" (foo 3 2))

改善されたコード生成の結果、最後の `str` 式は V8 では 3 倍、JavaSriptCore では 4 倍高速に評価されます.

変更リスト

ClojureScript 1.10.516 の更新の完全なリストについては、変更点を参照してください。

貢献者

ClojureScript 1.10.516 に貢献してくれたすべてのコミュニティメンバーに感謝します

  • Anton Fonarev

  • Enzzo Cavallo

  • Erik Assum

  • Eugene Kostenko

  • Martin Kučera

  • Michiel Borkent

  • Oliver Caldwell

  • Sahil Kang

  • Thomas Heller

  • Thomas Mulvaney

  • Timothy Pratley

  • Will Acton