世界を動かす技術を、日本語で。

OxCaml - OCamlプログラミング言語の拡張セット

概要

  • OxCaml はJane Streetが開発する OCaml拡張版
  • パフォーマンス指向 プログラミングに特化した機能追加
  • 安全性・利便性・予測可能性 を重視した設計思想
  • 既存のOCaml互換性 と進化する言語体験の両立
  • 実験的利用とフィードバック を歓迎するオープンソースプロジェクト

OxCamlとは何か

  • OxCaml は、Jane Streetが運用する OCamlコンパイラの拡張セット
  • パフォーマンス重視 のプログラム開発を支援する実験的プラットフォーム
  • OCaml本体への機能還元 を目指し、将来的な本家統合を視野
  • 既存のOCamlプログラム はそのままOxCamlでも動作可能
  • OCamlの進化形 として、使いやすさと生産性を維持

設計目標

  • 安全性 :プログラマの生産性向上と正確なコード提供
  • 利便性 :型推論の維持と、過度な注釈を強いない操作性
  • 予測可能性 :コードの挙動やパフォーマンスを型レベルで明示
  • 必要な場面だけ で追加機能を利用できる「 pay-as-you-go」設計
  • OCamlらしさ を損なわず、基本設計思想を尊重

主な拡張機能

  • Fearless concurrency
    • 型システム拡張による データ競合の静的排除
  • Layouts
    • メモリ上のデータ配置 をプログラマが明示的に指定
    • SIMD命令 へのネイティブアクセス
  • Control over allocation
    • アロケーション制御 でGC負荷軽減・キャッシュ効率向上
  • Quality of life
    • ポリモーフィックパラメータ
    • Include functor
    • ラベル付きタプル
    • イミュータブル配列
    • 日常開発を便利にする各種拡張

OxCamlの利用方法

  • オープンソース として公開、研究者や実験的ユーザーを歓迎
  • 拡張機能の安定性・後方互換性は未保証 (ただしOCamlとの互換性は維持)
  • 標準ツールセット を改良して提供
    • duneopam 互換のパッケージ管理
    • LSP-server によるエディタ統合
    • ソースコード整形・ドキュメント生成 ツール
  • Jane Street製ライブラリ の2形態提供
    • OCaml本家用 (拡張機能除去済み)
    • OxCaml用 (拡張機能フル活用)
    • 一部拡張は消去不可 のため、OxCaml専用ライブラリも存在
    • 本家OCamlへの拡張統合後、互換ライブラリも順次提供予定

Hackerたちの意見

このフォークから最初にアップストリームされた機能はラベル付きタプルで、OCaml 5.4に入る予定だよ。

不変配列もこのフォークから移植されて、5.4に統合されたよ。ただし、異なる構文になってると思う。

匿名のラベル付き構造体や列挙型は、プログラミング言語での私のトップの希望機能なんだ!例えば、Rustではラベル付きとラベルなし(つまりタプル)の構造体を定義できる。struct Foo(i32, i32); struct Bar{sum: i32, product: i32} でも、関数から返せるのは匿名のタプルだけで、匿名のラベル付き構造体は返せないんだ。fn can() -> (i32, i32) fn cant() -> {sum: i32, product: i32}

うん、これにはかなりワクワクしてるよ、たとえ小さなことに見えてもね。ML2024のこの特定の機能の著者による論文とトークもあるよ: - https://www.youtube.com/watch?v=WM7ZVne8eQE - https://tyconmismatch.com/papers/ml2024_labeled_tuples.pdf

sum:int * product:intはproduct:int * sum:intとは違う型だから、この例ではラベル付きタプルを使うことで、ペアを間違った順番で返したり、初期値の順序を混同したりするのを防げるんだ。うーん、F#の匿名レコードの方が好きかも。例えば、{| product = 6; sum = 5 |}みたいに。フィールドの順番は関係ないから、値がタプルじゃないしね。

これは「酸化」してるってことなんだけど、Rustと同じ機能を目指してるからなんだよね(例えば「恐れのない並行性」とか、GCを避けることが挙げられてる)。実際にRustを使ってるわけじゃないよね?ちょっと混乱するな。

そうだね、Jane Streetは「Oxidizing OCaml」っていうブログ記事をしばらくの間公開してるよ。

Rustは、カスタムトレースGCを使えば使えるようになると思うよ。一般的なグラフデータを扱う場合には役立つし、実用的なパフォーマンスも求められるからね。でも、この取り組みがRustと本当に機能的に同等になる前に、そうなるのはかなり先の話だと思う。あまり意味を感じないけど、もしかしたら簡単なところから手をつけて、重要なO(x)Camlのコードベースに焦点を当てるつもりなのかも。

そうそう、彼らはこの用語をしばらく使ってるね。最近の技術論文も「モーダルメモリ管理でOCamlを酸化させる」ってタイトルだったけど、「酸化」という言葉自体は論文の中で実際には言及されてないんだ。ちょっと変だと思うけど、確かにキャッチーだね。

皮肉なことに、Rust(言語)は鉄酸化物じゃなくて、カビの「Rust」から名付けられたんだよね。

新しいopamスイッチを試してる人がいたら、これを使うと便利だよ:env OCAMLPARAM="alert=-unsafe_multidomain,_," opam install cohttp-lwt-unix。アラートがエラーに昇格しちゃうから、既存のパッケージインストールが無駄に壊れちゃうんだ。OCAMLPARAM環境変数を使うと、そのアラートを無効にしてパッケージのインストールを続けられるよ。

これを作ったJanet Streetの人たちは、OCamlでのパフォーマンスに関する興味深いエピソード[0]のポッドキャストもやってるよ。私が気になってるのは、GC言語を極めて低レイテンシが求められるユースケースに適用することなんだ。高頻度取引の途中でGCが止まるのは問題になりそうだから、重要な考慮事項だと思う。[0] https://signalsandthreads.com/performance-engineering-on-har...

リンクは見てないけど、取引のようなシナリオでは、市場のオープンとクローズの時間があるから、GCを無効にして、市場が閉まった後にプログラムを再起動すればいいと思うよ。

GCのコンパクションは、いくつかのシステムにとって確かに問題だったよ。取引システムは一般的に、スタートアップ後はメモリを割り当てない方針だったし。JSには「Zero」っていうライブラリがあって、非割り当ての方法でいろいろできるんだ。

ゴミを溜めておいて、市場が閉まっている時に集めればいいんだ。取引で超低遅延が必要な場合は、大体は市場のオープンとクローズの時間がしっかり決まってるからね。常にオープンな市場(暗号通貨?)では違うかもしれないけど、ほとんどのHFTは通常の市場時間中に行われるよ。

*ジェーン・ストリート

このフォークがSIMDをサポートしてるとは知らなかった!これとアンボックス型、明示的スタック割り当てのローカルモードのおかげで、OxCamlは私のF#への興味をほぼ完全に置き換えちゃった。もしWindowsもサポートしてくれたら、ゲーム開発や似たような消費者向けシナリオに使えるようになるかもね。

うん、これは素晴らしいね!今は128ビットのSSE/NEONしか動いてないけど、AVXもすぐに来るよ。Windowsに関しては特に問題はないけど、ちょっと作業が必要になるかな。(OxCamlにSIMDサポートを追加したんだ)

そうだね、OxCamlはMLの方言の拡張の拡張なんだ。次のレベルが待ちきれないよ!

F#に興味ある?

OcaMLのマイクロな親戚: http://t3x.org/mlite/index.html

Jane Streetのサンクコストの誤謬は強烈だね。

彼らにとってはサンクコストの誤謬かもしれない。でも、彼らがいなかったら、Rustの80/20の利益/労力を得られる言語はなかったと思う。

何言ってるの?

MetaのPHPの話を聞いたら驚くよ…