7月7日、Alex Millerが「Clojure - Clojure 1.13.0-alpha3」と題した記事を公開した。Clojure 1.13.0のアルファ第3版(alpha3)のリリース内容が詳しく紹介されている。
Clojureのdestructuring(分割束縛)は、マップやシーケンスから値を取り出してローカル変数に束縛する強力な構文だ。しかし「個別のキーを変数に取り出しつつ、使ったキーだけをまとめたサブマップも欲しい」という場面では、これまで select-keys を別途呼び出すか :as で全体を受け取ってから加工するしかなかった。今回のalpha3はこのかゆいところに手が届く :select ディレクティブを中心に、パフォーマンス改善や新機能が含まれる。
目玉::select ディレクティブでサブマップ抽出が一行に
map destructuringの基本構文はこうだ。
(let [{:keys [x y]} m]
...)
これでマップ m から :x :y の値を変数 x y に束縛できる。しかし「 x と y を使いつつ、{:x ... :y ...} のサブマップを後続処理に渡したい」となると、これまでは次のような迂回が必要だった。
(let [{:keys [x y] :as m} full-map]
(let [sub (select-keys m [:x :y])]
...))
:select ディレクティブ(CLJ-2964)を使うと、同じことが一つの束縛フォームで書ける。
(let [{:keys [x y] :select [sub]} m]
;; x, y には個別の値
;; sub には {:x ... :y ...} のサブマップが束縛される
...)
:select には「どのキーをサブマップに含めるか」ではなく「サブマップを束縛する変数名」を指定する。含まれるキーは、同じ束縛フォーム内で :keys などを通じて名前を指定したキーが自動的に対象になる。バリデーション処理や部分的なマップ転送など、必要なキーだけを次の関数に渡すパターンで特に恩恵が大きい。仕様は CLJ-2963 で追跡されている。
destructuringはClojureが初期バージョンから持つコアの仕組みであり、実質すべてのClojureコードで使われる。その構文を直接拡張するこの変更は、言語レベルの変更としては珍しく大きな影響範囲を持つ。
パフォーマンス改善:select-keys の高速化とマップしきい値管理
select-keys の高速化(CLJ-1789)は、内部的にtransient(一時的な可変マップ)を活用した実装改善だ。select-keys はClojureコードベース全体で頻繁に登場する関数であり、日常的な処理速度への恩恵は小さくない。
もう一つの改善として、**RT.map(およびリーダー)が新しいPAM(Persistent Array Map)しきい値を追跡するようになった**。PAMはClojureの小規模マップ内部実装で、要素数が少ない間は配列ベースの構造を維持し、一定のしきい値を超えると自動的にHashMapへ切り替わる。今回の変更はそのしきい値管理を正確にするものだ。
新機能:セットが get で引けるようになる
セット(set)への ILookup 対応(CLJ-2958)も追加された。ILookup はClojureの get 関数や (:key coll) 呼び出しで使われる内部インターフェイスだ。これまでセットに対して get を使うと nil が返っていたが、今後はセット自体が ILookup を実装することで以下のように書ける。
(get #{:a :b :c} :a) ;; => :a
(get #{:a :b :c} :d) ;; => nil
マップやベクタと同じ記法でルックアップでき、コレクション間の統一的な扱いが進む。
バグ修正
以下のバグ修正も含まれる:
pprintが任意オブジェクトを読み取り不可能な形式で出力する問題(CLJ-2902)TaggedLiteralがprint-dupを定義していない問題(CLJ-2801)definterfaceがパラメータの型ヒントを解決しない問題(CLJ-2269)clojure.test/reportのdocstringに壊れた参照が含まれる問題(CLJ-2781)zipper・bytes/shorts/chars・scalb・clojure.math/floorのdocstringに関する複数の誤字・誤リンク修正
試し方
deps.edn の :deps に以下を追加すれば試せる:
org.clojure/clojure {:mvn/version "1.13.0-alpha3"}
Clojure CLIからそのままREPLを起動したい場合は(macOS/Linux):
clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.13.0-alpha3"}}}'
Clojure 1.13はまだアルファ段階であり、本番利用は推奨されない。:select ディレクティブはフィードバックを集めながら仕様が固められている段階だ。ダウンロードや詳細な利用方法は Downloadsページ を参照されたい。
詳細はClojure - Clojure 1.13.0-alpha3を参照していただきたい。