OCamlコンパイラのバックエンドを提供するMalfunctionが面白そう
OCamlのDiscuss掲示板を眺めていたらこんなプロジェクトについての言及があった:
Malfunction is a high-performance, low-level untyped program representation, designed as a target for compilers of functional programming languages.
OCamlコンパイラの中間表現であるLambda言語(とほぼ同等のもの)を受け取り、OCamlバイトコードかnativeコードへのコンパイルをしてくれるようだ。
(追記:バイトコードにコンパイルできるというのは間違い。実際にはOCamlコンパイラとは別なLambda言語インタプリタがある)
Lambda IRはOCamlコンパイラにフラグを渡すと出力してくれる。以前少し調べていくつか記事を書いた:
型検査後のフェーズの中間表現なので型情報は除去されており、Lambda IRで書かれたプログラムの型安全性を保証するものは何もない。すでに正しさが保証されたプログラムを渡されるのが前提となっている。
Malfunctionは関数型プログラミング言語関連の学会ICFP2016のMLワークショップで発表されたものらしく、ポジションペーパーが出ている:Malfunctional Programming
Malfunction is an untyped program representation intended as a compilation target for functional languages, consisting of a thin wrapper around OCaml's Lambda intermediate representation.
Compilers targeting Malfunction convert programs to a simple s-expression-based syntax with clear semantics, which is then compiled to native code using OCaml's back-end, enjoying both the optimizations of OCaml's new flambda pass, and its battle-hardened runtime and garbage collector
「実験言語のコンパイラ作ると『でもそれって速度出るの?』って聞かれて鬱陶しいので、正格評価な関数型言語のための速度が出るバックエンドとしてOCamlコンパイラの後ろのほうをハックした」ということらしい。
とりあえず他のやり方として
などとも比較されており
- LLVMなどはガベージ・コレクションと相性が悪い
- JVMや.NETはバイトコードレベルでJavaやC#の型システムとほぼ同等の型検査が走る。より精緻な型システムで検証されたプログラムの安全性をJava/C#の型システムに納得させるのは不可能ではないが手間だし無用な実行時チェックが入って非効率
- JavaScriptなどはランタイムとしても結構早いほうだが無駄な実行時チェックが入る
という点で不満がありOCamlのバックエンドを選ぶ理由になったとのこと。
個人的にMalfunctionに期待しているポイントとしては:
- OCamlなみに実行が早い
- OCamlなみにコンパイルが早い
- 正格評価な関数型言語に最適化されたランタイム
- OCamlとのinterop
- コンパイル選択肢としてOCamlバイトコードとバイナリ
- OCamlバイトコードはjs_of_ocamlに渡してJavaScript化が可能なはず (追記:前述のとおりバイドコードへのコンパイルがサポートされていないことがわかったのでjs_of_ocamlの利用は残念ながら不可)
あたり。
私はプログラミング言語の意味論的にはMLベースなものを自然と想定する部族の一員なので、自作言語にOCamlのバックエンドを丸々使えてしまうというのは垂涎もの。是非とも自分の言語処理系ツールの一つとして使いこなしたい。