Mino: ポータブル C99 に Clojure 風エルゴノミクスをもたらす
埋め込み可能なスクリプト言語の世界では、開発者は Lua のような軽量言語と、モダンな関数型言語が提供する強力なデータ処理エルゴノミクスの間でトレードオフに直面することが多いです。Mino は、ポータブル C99 で書かれた Clojure 風 Lisp を提供することでこのギャップを埋げ、既存のホストアプリケーションに最小限の摩擦で組み込めるよう設計されています。
小さなメモリフットプリントと永続的な不変データ構造、そして能力ベースのセキュリティモデルを組み合わせることで、Mino は JVM や重いランタイムのオーバーヘッドなしに、柔軟でサンドボックス化されたスクリプト層を必要とする開発者にとって魅力的な代替手段を提供します。
埋め込みの階層的アプローチ
Mino は「階層(tier)」という概念を中心に設計されており、開発者は必要とするフットプリントと機能性の正確なバランスを選択できます。このモジュラリティにより、言語は「組み込み可能なほど小さく」かつ「実用的な速度」を保ちます。
1. Floor(最小)
このランタイムの最も軽量なバージョンで、リーダ、評価器、ガベージコレクタ、永続的コレクション、数値演算、基礎的マクロという絶対的必須要素に焦点を当てています。core.clj の評価を除外しており、フットプリントは約 613 KB と非常に小さく、初期化時間は驚異の 0.23 ms です。
2. Standard(フル Clojure サーフェス)
Floor 階層を基盤に、Standard バージョンは Clojure スクリプターが期待する機能、すなわち正規表現、ビッグナム、マルチメソッド、プロトコル、トランスデューサを追加します。この階層ではフットプリントがやや増えて 728 KB となり、初期化コストは 5.3 ms です。特筆すべきは、この階層もサンドボックスであり、ホストが明示的に許可しない限り I/O 機能は提供されません。
3. Standalone(フルスイート)
Standalone 階層は完全版で、I/O、ファイルシステムアクセス、ソフトウェアトランザクショナルメモリ(STM)、エージェント、非同期機能、バンドルされた clojure.* 標準ライブラリ、そして REPL を含みます。フットプリントは 987 KB、初期化時間は 5.5 ms で、Clojure に似た環境の全体体験を提供します。
パフォーマンスとポータビリティ
Mino の主な強みの一つはコールドスタート性能です。x86_64 Linux における Floor 階層の実時間コールドスタート(50 回の中央値)は 1.04 ms です。これは Lua 5.5(0.78 ms)と同等のレベルで、Janet(1.95 ms)よりも高速であり、プロセス生成時間が重要な環境に適しています。
ポータブル C99 で書かれているため、Mino は C FFI を持つほぼすべてのホスト(C++、Rust、Go、Java、.NET、Swift、Zig など)に埋め込むことができます。外部ランタイムや JIT、デーモンは不要で、ホストプロセスが実行を完全に制御します。
アーキテクチャの柱
分離されたランタイムとメモリ安全性
各 Mino ランタイムは専用のヒープとガベージコレクタを持つ独立した障害ドメインとして動作します。共有可変状態や競合状態を防ぐため、ランタイム間でデータをやり取りする際はディープコピーで処理します。このアーキテクチャにより、単一プロセス内で複数のテナントを完全に分離してホストできます。
能力ベースのインターロップ
セキュリティはランタイム設計に組み込まれています。新しい Mino ランタイムはゼロの能力で開始し、ファイルシステムアクセス、ネットワークアクセス、環境状態は一切ありません。埋め込み側は各能力を明示的に許可し、スクリプトが呼び出せるホスト側の型やメソッドを登録する必要があります。
Clojure 風エルゴノミクス
スクリプターにとって、Mino は Clojure を強力にする高レベル抽象を提供します:
- 永続的な不変データ構造: エイリアスバグや「誰がテーブルを変更した?」という驚きを排除します。
- 遅延シーケンス: 無限に近いデータストリームの効率的な処理を可能にします。
- 末尾呼び出し最適化: 再帰関数(
drainのような操作)をスタック領域一定で実行できるようにします。 - REPL 主導のワークフロー: ホストアプリケーションを再コンパイルすることなく、ライブ検査や実行時設定の変更をサポートします。
実装例:3 つのロールワークフロー
Mino は 3 つの主要ロール間で関心の分離を明確に定義します:
- アプリケーション開発者: ランタイムを埋め込み、特定の能力を許可することでセキュリティ境界を定義します。
- C++ エンジニア: ホスト側の型をスクリプトに公開します。ホストオブジェクトは型タグ付きハンドルとしてラップされ、GC が自動でクリーンアップします。API がスタックインデックスではなく直接値ポインタを使用するため、従来の C ベース埋め込み API によくあるオフバイワンインデックスエラーを防げます。
- スクリプター: Lisp 構文でビジネスロジックを記述します。ホストオブジェクトをあたかもネイティブ Mino 型のように扱い、キーワードをデータアクセサとして、コレクションを呼び出し可能な述語として利用します。
想定されるユースケース
設計上、Mino は特に次の用途に適しています:
- ルールエンジン & ポリシー: ホスト状態を Mino の述語に公開し、宣言的ビジネスロジックを実現します。
- プラグインシステム: ユーザーが作成したスクリプトを厳格にリソース制限し、環境アクセスを許可しない形でロードします。
- データパイプライン: 永続的コレクション上で
map、filter、reduceを構成し、構造共有を活かします。 - ゲームスクリプティング: プレイヤー向けにプログラマブルコンソールを提供し、サンドボックスとステップ制限で無限ループやクラッシュを防止します。
- インタラクティブコンソール: アプリ内に REPL を埋め込み、ライブデバッグや実行時設定を可能にします。