LunarML進捗・2023年9月

夏の進捗報告です。

前回:

目次

進捗

ES modulesへの対応

これまでのLunarMLでは、Node.jsの機能を使うのに require でモジュールをロードしていました。CommonJSです。

しかし、他のランタイム(Webを含む)にも対応していくことを考えると、ES modulesを使った方が良いです。そこで、Node.jsであってもES importを使うようにしました。

require は関数だったのに対し、ES importは構文です。dynamic importという、関数でラップできそうなやつもありますが、静的なimportも出力できた方が良いと思い、 _esImport { foo } from "some_module" という形の構文(宣言)を追加して、JS出力時に巻き上げて import 文を生成するようにしました。

Node.jsでES modules形式のスクリプトを実行するには、拡張子を .mjs にするのが手っ取り早いです。なので、デフォルトの拡張子もそうしました。もちろん、オプションで出力ファイル名を指定すれば .js も出せます。

ついでに(?)、ES exportも生成できるようにしました。Luaと同様に、export という名前の変数を定義するとそれが唯一の値としてexport(JSではdefault export)され、export という名前のstructureを定義するとそれのメンバーがexport(named export)されます。

非CPSモードの場合は素直にexportできますが、CPSモードではトップレベルで非同期な関数呼び出しをしたらどうするかという問題があります。最近のJavaScriptにはtop-level awaitがあるのでそれを使うのでも良いのですが、今はひとまずトップレベルでは継続を取れないようにして(promptをpushしないようにして)います。

リリースへ向けて

年内にバージョン0.1をリリースしたいです。そのための準備を少しずつ進めています。

仕様変更

リリース後に大きな仕様変更はなるべくしたくないので、今のうちにガンガン仕様変更をしています。変更の例を挙げます:

  • LuaJITバックエンドとJSバックエンドで、デフォルトの int 型を32ビット整数から54ビット整数に変更しました。
  • Node.js向けの出力を生成するオプションを --js から --nodejs へ変更しました。
  • JavaScript.toInt32/toUint32 の型を変更しました。
  • $(SML_LIB)/basis/basis.mlb から色々非標準のものを露出するのをやめて、個別の .mlb ファイルに移しました。

機能追加

ライブラリーの細かい機能追加も行なっています。Dateとかを実装しました。

SMLUnitが動けば良いのですが、まだ遠そうです。

パッケージング

配布の準備もしています。

しかし、各OS向けのバイナリーを用意するのは面倒です。GitHub Actionsでやってもらえば良いのかもしれませんが、AArch64向けのMLtonがパッケージマネージャーで入らないので、大変そうです。

そこで、別の方法を考えます。

まず、Dockerです。Dockerを使えば一つの(Linux向け)バイナリーを複数のOSで動かすことができます。アーキテクチャーはMLtonの関係でx86_64 (amd64)に制限されますが、AArch64でもQEMUと連携してうまいこと動かしてくれます。GitHub Actionsを使って、タグをpushしたら自動でイメージをビルドしてghcrにpushするような仕組みを構築するところまでできました。

次に、npmです。コンパイラーをJavaScriptにコンパイルしてしまえばアーキやOSへの依存は発生しません。その代わり実行がネイティブバイナリーに比べると遅くなります。こちらはローカルでnpxで動かせることは確認しましたが、パッケージングの自動化までは至っていません。

Nixというやつもあります。私はよくわかっていませんが、親切な人がnixpkgsに書いてくれているのでこのままで大丈夫そうです: nixpkgs/pkgs/development/compilers/lunarml/default.nix at master · NixOS/nixpkgs まあこれはx86_64でしか動かないかもしれません。

もちろん、ソースパッケージも重要です。make installで好きな場所に入るようにしたいです。

MLton以外のSML処理系に目を向けると、Poly/MLがArm対応を謳っているので、Poly/MLに対応するという手も考えられます。

将来的には、LunarML/Nativeみたいな感じで独自のネイティブコンパイラーを持てると良いのかもしれませんが、時間と労力が必要ですね。

広報

このブログは日本語ですが、こことは別に英語ブログを準備中です。リリースのアナウンスとかはそっちでもやるつもりです。

あと、万が一支援したい人が現れた時のために、GitHub Sponsorsに登録してみました。ただ、どういうtierを用意するのがいいのか正直よくわかっておらず、手探りです。


今回の進捗報告は割と地味でした。LunarMLに関する次回の記事がv0.1リリースのお知らせになるように、頑張りたいです。