Flix – 強力なエフェクト指向プログラミング言語
(flix.dev)- FlixはAarhus Universityとオープンソースコミュニティが開発するエフェクト指向言語で、関数型・命令型・論理プログラミングを1つの言語内で組み合わせる
- 中核は副作用を型レベルで扱うエフェクトシステムで、純粋性の追跡・ユーザー定義エフェクト・ハンドラー・複数回再開により、モジュール性と推論可能性を高める
- 言語の表層は、代数的データ型、パターンマッチング、拡張可能なレコード、トレイト、高階kind型、関連型・関連エフェクト、構造化並行性、Java相互運用性、組み込みDatalogまで幅広い
- 標準ライブラリは3,100個以上の関数を提供し、Maven経由でJavaエコシステムにもアクセスできるため、研究用言語にとどまらない利用範囲を目指している
- コンパイラはJVMバイトコードをターゲットとし、並列・インクリメンタルな構造を備え、24コアマシンで5x–7xの高速化と、Apple M2 Pro/OpenJDK 21基準で60,159 lines/secの処理量を掲げる
Flixの言語の方向性
- Flixは原則ベースのエフェクト指向言語で、関数型・命令型・論理プログラミングを組み合わせる
- 開発主体はAarhus Universityとオープンソース貢献者のコミュニティ
- エフェクトシステムは副作用を明示的にモデル化し、モジュール性とプログラム推論を助ける静的型付け言語の中核的な軸
- ユーザー定義エフェクトとハンドラーにより、プログラマーが制御構造を直接実装できる
- Flixは、エフェクト指向言語の中でも完成度の高い実装、広い標準ライブラリ、詳細なドキュメント、ツールサポートを強みとしている
型、純粋性、エフェクトシステム
- Flixは関数型プログラミングの基本要素である代数的データ型とパターンマッチングをサポートする
- タプルとレコードを組み込みでサポートし、レコードは構造的型付けを使用し拡張可能
- コンパイラはプログラム内のすべての式の純粋性を精密に追跡する
- 式が純粋であれば、副作用がなく参照透過であることを保証する
- 高階関数でもエフェクト多相性によって純粋性を追跡する
- 例えば
List.mapの純粋性は、引数として受け取る関数fの純粋性によって変わる
- 例えば
- 代数的エフェクトにより、ユーザー定義エフェクトとハンドラーが可能になる
- Flixは特にmulti-shot resumptionsをサポートする
- エフェクトハンドラーは、プログラム推論、モジュール性、テスト可能性を高めるために使われる
リージョンベースの変更と純粋性リフレクション
- Flixはリージョンベースのローカルな変更をサポートし、変更可能な状態と破壊的操作を内部的に使いながらも、外部からは純粋関数に見せることができる
- 変更可能なデータで書く方が自然な関数や、ソートアルゴリズムのように変更可能なデータ構造の方が効率的な場合に適している
- 純粋性リフレクションは、高階関数が関数引数の純粋性を検査し、その情報に基づいて振る舞いを変えるメタプログラミング構造
DelayList.mapは引数関数の純粋性に応じて、即時評価と遅延評価の間で振る舞いを変える- ライブラリ内部で遅延評価や並列評価を選択的に使っても、クライアントから見た意味は変わらない場合がある
並列性、並行性、抽象化
- Flixは純粋なコードを並列に評価しやすくし、
par構造でList.mapの並列実装を書ける par構造は内部的に軽量なVirtualThreadを使用する- 構造化並行性をサポートし、特定のリージョン内で作成されたスレッドは、そのリージョンのライフサイクルを超えて生き残ることはできない
- 例では
rcという新しいリージョン内で2つのスレッドを作成する - 制御フローは2つのスレッドがどちらも終了するまでリージョンを抜けない
- 例では
- 共通操作をサポートする型抽象化にはトレイトを使用する
Eqトレイトは等価性の概念を表し、標準ライブラリ全体で使われる
- 高階kind型により、型コンストラクタを抽象化できる
OptionとListはいずれもFoldableを実装する- 標準ライブラリには
Monoid、Functor、Foldableのような共通トレイトが含まれる
関連型・関連エフェクトとfor-yield
- Flixは、インスタンスシグネチャの型がインスタンス型に依存できるようにする関連型をサポートする
Collトレイトの例では、関連型Elmによって各コレクションインスタンスが要素型を定義できるようにする
- 関連エフェクトは、トレイトメンバーのエフェクトがインスタンス型に依存するようにする
- 純粋な操作とエフェクトのある操作、変更可能なデータ構造と不変データ構造をまとめて抽象化しやすい
Collトレイトに関連エフェクトAefを追加すると、変更可能なコレクションインスタンスを追加できる
forM-yieldは、Scalaのfor-comprehension、Haskellのdo記法に似たモナド構造Monadトレイトが提供するpointとflatMapを使うための構文糖
forAはApplicativeトレイトベースの適用型式Validation[e, t]データ型を使うエラー処理コードを簡単に書けるようにする構造
Java相互運用性とDatalog
- FlixはJava Standard LibraryとJavaエコシステムのコードを再利用できるJava相互運用性をサポートする
- Mavenを通じたエコシステムへのアクセスを含む
- オブジェクト生成、メソッド呼び出し、例外、クラス・インターフェースの拡張をサポートする
- 組み込みDatalogサポートはFlix固有の機能の1つ
- Datalogはグラフ到達可能性問題を含む、さまざまな不動点問題を簡潔に表現できる
- Datalog制約は第一級値
- 関数に渡したり、関数から返したりできる
- データ構造に保存できる
- 他のDatalog制約と合成し、解くことができる
- これによりDatalogプログラムの系列を表現できる
- Flixは束意味論で拡張されたDatalog制約もサポートする
- 部品と下位構成品の配送日を計算する例がある
- 自動車はシャシーとエンジンに依存し、それぞれの構成品の組み立てを待った後に自動車を組み立てられる
- 下位構成品も別の下位構成品に依存し得るため、問題は再帰的
- 束意味論を含むDatalog制約はFlixの高度な機能の1つであり、束理論と不動点の背景知識が必要
標準ライブラリと機能一覧
- Flixは3,100個以上の関数を提供する標準ライブラリを含む
Listモジュールは100個以上の関数を提供するFoldableトレイトは47個以上の関数を提供する- ライブラリ全体はapi.flix.devで閲覧できる
- 機能一覧には次が含まれる
- 代数的データ型、パターンマッチング、第一級関数
- 拡張可能なレコード、パラメトリック多相性
- トレイト、高階kind型、関連型と関連エフェクト
- エフェクト多相性とサブエフェクト、純粋性リフレクション
- CSPスタイルの並行性、バッファありチャネルとバッファなしチャネル
- 第一級Datalog制約、Java相互運用性
- アンボックス化プリミティブ型、キーワードベースの構文
forM、forA、式hole- JVMバイトコードコンパイル、完全な末尾呼び出し除去
- 弾力的・並列なコンパイラ構造、人間が読みやすいエラー
コンパイラ構造と性能
- Flixコンパイラは弾力的・インクリメンタル・並列な構造を備える
- すべてのコンパイラ段階が並列であり、24コアマシンで各段階の高速化を活用できる
- マルチコアマシンでは5x–7xの高速化が可能
- 同じコンパイラインスタンスで、すでにコンパイル済みのコードを再コンパイルする際には、インクリメンタルコンパイルによって大幅な高速化を得られる
- Apple M2 Pro 10コアCPUとOpenJDK 21基準の性能値は次の通り
- コンパイラ全体の処理量: 60,159 lines/sec
- フロントエンドのみの処理量: 140,382 lines/sec
- 再現コマンドは
java -jar flix.jar Xperf --n 21およびjava -jar flix.jar Xperf --frontend --n 21
- この性能は、型・エフェクト推論、単相化、全プログラム最適化のようなコストの大きい言語機能をサポートしながら達成した数値
- コンパイラ性能は主にCPU性能とメモリ帯域幅によって決まる
Visual Studio Codeサポートとツール統合
- FlixコンパイラはVisual Studio Codeと統合され、開発環境を提供する
- VSCode拡張は実際のFlixコンパイラを使用するため、拡張とコンパイラの間に1:1の対応がある
- VSCodeがエラーを報告しなければエラーはない
- エラーがないときにVSCodeが偽のエラーを報告しない
- VSCode拡張は次の機能をサポートする
- 意味ベースのシンタックスハイライト
- インラインのコンパイラエラー診断
- 入力中の自動補完、コンテキスト認識自動補完、トレイトインスタンス自動補完、型ベースのhole補完
- スニペットとインレイヒント
- 式の型とエフェクトを表示するhover
- 関数、ローカル変数、enum定義への移動
- 関数・ローカル変数・enum参照の検索とトレイト実装の検索
- ドキュメント・ワークスペースシンボル一覧
- ローカル変数と関数名の変更
- エディタからのmain実行とテスト実行
- Flixは多くのツールをコンパイラに直接組み込む
- OCamlはLSPに
ocaml-lsp、REPLにutop、ビルドツールにdune、パッケージマネージャにopamを使用する - HaskellはLSPに
HLS、REPLにghci、ビルドツールとパッケージマネージャにcabal、stack、パッケージリポジトリにHackageを使用する - Flixはコンパイラ、LSP、REPL、ビルドツール、パッケージマネージャをすべて
flixで提供し、パッケージリポジトリはGitHub
- OCamlはLSPに
開発状況、JVMターゲット、プロジェクト規模
- FlixはデンマークのAarhus Universityのプログラミング言語研究者が開発・保守している
- 協力機関はカナダのUniversity of Waterloo、ドイツのUniversity of Tubingen、デンマークのCopenhagen University
- 世界中のオープンソース貢献者コミュニティによる開発参加が増えており、貢献を歓迎している
- プロジェクト統計は次の通り
- マージされたPull Request: 4,900件以上
- 解決済みイシュー: 3,100件以上
- 貢献者: 70人以上
- コンパイラコードベース: 272,000行以上
- FlixはJVMをターゲットとする
- JVMにはOpenJDK、J9、Azul、Graalなど、検証済みのオープンソース・商用実装がある
- Mac、Linux、Windowsで利用できる
- 現代のJVMは複数の最新ガベージコレクタを提供する
- Java 21の軽量スレッドを含め、並行性と並列性のサポートが優れている
- デバッガとプロファイラを含むツールサポートがある
- Maven統合により、Javaプラットフォームの豊富なパッケージエコシステムにアクセスできる
- 総資金調達額は110万ユーロで、プロジェクトの継続性と独立性の確保に役立っている
まだコメントはありません。