Clojure 1.7がTransducersを導入,クロスプラットフォームサポートを改善

TransducersとReader Conditionalsの2つは,Clojure 1.7で最も重要な機能だ – CognitectのAlex Miller氏は言うTransducersが目指すのは,さまざまなコレクションを対象とした,構成変更の可能なアルゴリズム変換機構の実現である。またReader Conditionalの方は,JVMとJavaScriptプラットフォーム間で,Clojureの可搬性を向上するものだ。

Transducers

TransducersとはReducing Function用のTransformer,つまりReducing Functionを取得して,別のReducing Functionを返すような関数である。Reducing Functionとは,reduceで使用可能な関数のことを言う。Rich Hickey氏は,Transducersの最大のメリットについて,次の3つの主要な関心事を分離可能にすることだと説明している

  • Reducing Functionが何を行うのか
  • 適用されるコレクションの種類
  • reduceへの入力

Transducersをサポートするため,mapcat, filterなどClojure 1.7のシーケンス関数の大部分に,入力コレクションが省略された場合の引数形式が追加されている。例えば,

(def tr1 (map f))

これはmapのTransducerを返す。さらにTransducersは,comp関数を通じて構成することも可能だ。

(def xform (comp (filter odd?) (map inc)))

この式は新しいTransducerを提供する。Transducerができれば,ベクタデータなどいくつかの方法でそれを適用することが可能になる。

(Sequence Xform data)

Sequenceに代えてTransduce関数を使用すれば,datareduceを適用した時と同じ結果と,独自の合成関数が得られる。

上にあげたサンプルコードの最大のメリットは,生成される遅延シーケンスがただひとつであることだ。単純な関数合成を使用した場合のように,3つの遅延シーケンスが生成されることはない。

Reader conditionals

Reader Conditionalsは,.cljcファイルのコンテキストで有用な機能だ。.cljcファイルはClojure 1.7で新たに導入されたフォーマットで,ClojureあるいはClojureScriptのいずれからもロードできる。このアプローチによって,ライブラリや,ひとつのコードベースで複数のClojureプラットフォームをターゲットにすることが可能になる。そしてReader Conditionalsは,プラットフォーム特有のコードの扱いを容易にするメカニズムを提供する。

Reader Conditionalsの式では,condと同じような形式で,各プラットフォーム上で使用されるプラットフォーム固有コードを指定することができる。例えば,次の式は,

[1 2 #?@(:clj [3 4] :cljs [5 6])]

Clojureでは[1 2 3 4],ClojureScriptでは[1 2 5 6]と評価される。

TransducerやReader Conditional以外にも,Clojure 1.7ではさまざまな機能や拡張が導入されている