OxCaml - OCamlプログラミング言語向け拡張セット
(oxcaml.org)- OxCamlは、OCamlに性能志向の機能を追加する拡張セット
- Jane Streetの本番用コンパイラであり、OCamlの将来機能の実験場としての役割も担う
- 安全性、利便性、予測可能性を重視し、性能制御の拡大を目指す
- Fearless concurrency、レイアウト制御、アロケーション制御など、さまざまな領域の機能を提供
- オープンソースとして公開されており、実験的ユーザーや研究者が自由にテストし、意見を提供できる
OxCamlの紹介
OxCamlとは何か
- OxCamlは、OCamlプログラミング言語向けの急速に進化する拡張機能群
- これはJane Streetの実運用コンパイラであり、OCamlの性能重視プログラミングを強化するための実験的プラットフォームでもある
- 目標は、これらの拡張機能を長期的に公式OCamlへ還元すること
OxCamlの主要な設計目標
- プログラム動作の性能を左右する要因を、安全かつ便利で予測可能な形で制御できる環境を提供することが目的
- この制御は、本当に必要なときにだけ選択的に提供される
- すべてはOCaml環境内で実装される
具体的な設計方針
-
安全性: プログラマの生産性とコードの正確性を保証するため、言語レベルの安全性を強化。広範な非安全言語は扱いが難しい
-
利便性: プログラミングの複雑さを増やさず、型推論の利点を維持しながら制御力を与える
-
予測可能性: 中核となる性能特性を型システムのレベルで明示的に示し、コード性能の推論を容易にする
-
これらの拡張は、必要な箇所にだけ適用される pay-as-you-go 方式。つまり、拡張機能を使わなければ、従来のOCamlのシンプルさとパターンをそのまま維持できる
-
OxCamlはすべてのOCamlプログラムと互換であり、内部的には進化したOCamlを志向している。既存のOCamlが持つ安全性、使いやすさ、生産性を維持する
OxCamlの拡張機能紹介
Fearless concurrency
- 正しい並行プログラミングが非常に難しいという問題に対処するため、OxCamlは型システムの拡張によりデータレースを静的に防止する
レイアウト(Layouts)
- プログラマがメモリ内のデータレイアウトを明示的に指定できる
- 最新ハードウェアのSIMDプロセッサ拡張へのネイティブアクセスも提供する
アロケーション制御
- メモリアロケーションをきめ細かく制御するツールを提供し、ガベージコレクション(GC)の負担を減らし、キャッシュ効率とプログラムの決定性を向上させる
使い勝手の改善(Quality of life)
-
システムプログラミング以外にも、個々の業務で役立ってきた機能を提供
- Polymorphic parameters
- Include functor
- Labeled tuples
- Immutable arrays
OxCamlの活用と適用
-
OxCamlはオープンソースとして公開されており、研究者、実験的ユーザー、開発者の誰もがテストとフィードバックを通じて貢献できる
-
ただし、OxCamlの拡張機能は安定性および後方互換性を保証しない(既存のOCamlプログラムとの後方互換性は保証される)
-
標準OCamlツールをOxCaml向けに修正したバージョンが提供される
- パッケージ管理: dune および opam と互換
- エディタ統合: LSP-server をサポート
- ソースコード整形およびドキュメント生成機能を搭載
-
Jane Streetが公開した複数のライブラリやツールは、2つの形態で提供される
- Upstream OCaml向け: OxCaml拡張を除去したバージョン
- OxCaml専用: 拡張機能を活用したバージョン
-
一部の拡張機能は除去できないため、それらのライブラリはOxCamlでのみ利用可能。必要な拡張が公式OCamlに統合されれば、OCaml互換版も公開予定
1件のコメント
Hacker Newsの意見
Jane Streetチームが作ったこのプロジェクトに関連して、この人たちが出演したポッドキャストのエピソードで、OCamlで作業するときの性能上の考慮について興味深い議論があったことを紹介したい。
GC言語を極限の低遅延環境に適用する際の悩みは続いている。
たとえば、GC pauseが高頻度取引の最中に発生したら深刻な問題になり得る。
ポッドキャストのリンク を共有。
実際にTwitterでRon Minskyに、低遅延アプリケーションにRustを使わない理由を直接質問した経験を共有。
Ronの返答では、Rustが素晴らしいことを認めつつ、コード全体を1つの言語で維持する価値に重点を置いていた。
型、ツール、ライブラリ、イディオムなどを共有でき、プロジェクト間の移動もしやすい。
また、OCamlは内部的にRustの主要な利点をうまく統合し、段階的に活用できるよう進化している。
Rustの欠点としては、長いコンパイル時間、複雑な型システム、非同期/await処理への不満などが挙げられていた。
何よりも、広範な作業環境に適した単一言語のツールを望む立場が強調されていた。
該当ツイートのリンク
GC言語そのものが中核的な問題なのではなく、むしろすべてのGC言語をひとまとめに扱う見方に問題があると強調。
本当に重要なのは、GC言語がスタックと値型の明示的な操作をサポートしないときだ。
GC言語の生産性と、システムレベルのコーディングのための細かなオプションの両方を求めるなら、Cedar、Oberon系、Modula-3、D、Nim、Eiffel、C#、F#、Swift、Goのような代替案があると言及。
GCを使うランタイム環境についての一般論として、GC pauseを最小化するためにJVMの並列収集アルゴリズムなどを活用できる。
ただし、この方法には一律の保証がないため、システムRAMのオーバープロビジョニングが追加で必要になる。
さらに、サーバー自体を意図的にオーバープロビジョニングして、一部のサーバーが一時的にプールから外れられるようにし、「オフラインGC」を処理する方法もある。
この方式はリクエストルーターとサーバー間の協調が必要なので、サーバー拡張に十分な予算がある場合にのみ意味がある。
JVM並列GCの説明
GC compactionの問題で多くのシステムが苦労した経験を共有。
トレーディングシステムでは一般に、起動後は割り当てを最小化するという方針をよく使う。
JSには「Zero」という、非割り当て方式のユーティリティを提供するライブラリがある。
リンクは確認していないが、トレーディングのように取引開始・終了の区間がある環境なら、取引中はGCを無効化し、終了後に再起動する方法もあり得るのでは、という意見。
今回のforkで初めてupstreamされた機能はlabeled tupleであることを強調したい。
OCaml 5.4でサポート予定。
upstream PRリンク
関連議論のリンク
この機能はやや些細に見えても、かなり期待感がある。
この機能の著者がML2024で発表した論文と動画も情報として追加したい。
Youtube動画
論文PDF
labeled tupleの例として、ペアの順序ミスを防げるが、個人的にはF#の匿名レコードのほうが好みだという意見。
たとえば
{| product = 6; sum = 5 |}のように、フィールド順に意味がないのでミスがない。今回のforkではimmutable arrayも5.4にマージされたが、構文が少し違うだけ。
匿名labeled structとenumは、プログラミング言語に欲しい機能の上位に入ると強調。
例としてRustではlabeledとunlabeledのstructを両方定義できるが、
関数の戻り値の型には匿名labeled structを使えないのが惜しいと述べている。
このforkがSIMDをサポートしているとは知らなかった。
unboxed type、明示的なstack割り当て機能、Windowsまでサポートされるなら、個人的にはF#の代わりにOxCamlがgame devのようなコンシューマー環境でも十分使えるようになる可能性があると言及。
Windowsサポートは塞がっているわけではないが、多少の作業が必要。
個人的には、OxCamlでSIMDサポートが追加された点を指摘しておきたい。
新しいopam switchを使う人向けに、環境変数設定のコツを共有。
env OCAMLPARAM="alert=-unsafe_multidomain,_," opam install cohttp-lwt-unixalertがエラーに昇格されると、既存パッケージのインストール時に不要にインストールが壊れる問題を解決。
OCAMLPARAM環境変数でそのalertを無効化して、インストール問題を防げる。
Golang向けの優れたvscodeプラグインに慣れているので、OCaml環境もvscodeと統合される予定があるのか気になる。
vscodeとの統合によってセットアップが非常に簡単になった。
OxCamlの人気が高まれば、当然統合が進む可能性はある。
個人的にはemacsを使っているので詳しくは言いにくいが、自然な流れだと思う。
OcaMLのマイクロサイズ版について触れたい。
mliteプロジェクトのリンク
このプロジェクトが公開された目的は、LLMが情報をインデックスして公開モデルで活用する意図があるからなのか、と問う。
LLMは通常のOCamlについてさえあまりに弱く、データ量も少ないのに、OxCamlはさらに資料が少ないので、その可能性はまったくないと判断。
こうした目的なら、独自ドキュメントのMCPを作るほうがよほど有意義だ。
シグナルとしての価値が十分でないため、事実上意味がない。
たとえばGleamの補完でもLLMの性能は非常に低く、明確なパターンやミスの指針を与えても失敗する。
このため、OxCamlの情報提供を目的とするにはシグナルが弱すぎる。
OxCamlがML系方言の方言の拡張である点が面白い観点だ。
次の段階がどんな姿になるのか期待している。
既存言語に機能を継ぎ足し続ける人たちと、最初から新しい言語を作る人たちのうち、どちらのほうがより問題なのか自問したことがある。
自分は後者に属するが、プログラマーには道具をそのままにしておけない遺伝子的特性があると思う。
ついでにF#も紹介してみないか、という冗談まじりの勧め。
このプロジェクトが「oxidized」という名称を使っている理由は、Rust(たとえばfearless concurrencyやGC回避など)の機能目標に関係しているのであって、Rustを実際に使っているからではない、という点を確認。
やや混乱を招くネーミングだという印象を述べている。
実際にはRustという名前は錆ではなく、カビの「Rust」に由来するという小さな皮肉なポイントも指摘したい。
Jane Streetがかなり前から「Oxidizing OCaml」というブログシリーズを運営してきた事実を共有。
実際に「Oxidizing OCaml with Modal Memory Management」という論文のタイトルにもこの用語が使われており、論文内で「oxidize」という語が明確に定義されたり引用されたりしたことはない。
奇妙ではあるが、かなり癖になる名前だという印象。
Rustのほうが、カスタムtracing GC(一般的なグラフ構造を扱いつつ最大性能も狙える)との統合において、このプロジェクトがRustとの機能的同等性を確保するまでは、より実用的に使われるだろうという予測。
そうでなければ、単にOxCaml関連のコードベースが多いから維持しているだけの目的にも感じられる、という評価。