LunarMLの進捗2023と、今後の方針

LunarMLの今年の進捗を振り返ります。

これまでの記事へのリンク:

今年の進捗まとめ

今年やったことをざっくり箇条書きで振り返ります。

  • エスケープしない継続はジャンプやwhileにコンパイルする(1月)
  • CPS中間言語に対する最適化(随時)
  • CPS中間言語での例外の扱いを変更(1月)
  • CPS経由でdirect styleなLua/JavaScriptコードを生成する(1月〜2月)
  • Time/Timerの実装(2月)
  • Int54の実装(2月)、いくつかのバックエンドでデフォルトのintを54ビットにする(6月)
  • 【独自拡張】ドットによる中置演算子(3月)
  • 末尾再帰をループ(再帰的な二級継続)に変換する(3月)
  • エスケープしない関数や継続がタプルを受け取るときにunpackする(4月)
  • パターンマッチの網羅性検査と冗長性検査(5月〜6月)
  • 【独自拡張】型のドキュメンテーション(6月)
  • sequenceNonUnit(6月)
  • Dateの実装(7月)
  • ES import(7月)
  • ES export(8月)
  • Dockerfileの追加(9月)
  • 雑多なSuccessor MLの機能の追加(10月)
  • make installの実装(10月)
  • OS.PathのWindows対応(12月)
  • 型検査器の改造(12月)
  • v0.1.0リリース(12月)

色々やりましたね。細かい機能が多めかもしれません。

直近の進捗

9月以降の進捗についてもう少し書きます。

リリースするにあたってチェックリストが埋まっていた方が良いので、Successor MLの雑多な機能(すぐに実装できる機能)を実装しました。

make installを実装しました。インストールされるlunarmlは、ライブラリーのパスを埋め込んだラッパーにしました。PATHを利用して呼び出されるとargv[0]には絶対パスが入らないので……。

OS.PathはClutTeXでも使いたいので、Windowsにも対応させました。実行時にOSを見て実装を切り替えます。LuaでOSを識別するのには package.config の1文字目を使うことにしました。ただ、SMLのOS.PathのWindows対応はUNC pathを想定していない気がするので、その辺は改善の余地があります。

最近bidirectional typingというものに感化されたので、型検査器をそれっぽく書き換えました。といっても、これまでも「文脈から期待される型」がある場合はそれを渡すようになっていたのですが。現時点ではHM型推論で十分なので、bidirectional typingの効能はそんなにないのですが、エラーメッセージをわかりやすくできるかもしれません。また、将来的に型に関する拡張を導入した場合に役に立ってくれるはずです。

そして、v0.1.0をリリースしました。英語でも記事を書いて/r/smlとStandard ML Zulipに流しましたが、元々の人口が少ないからか、あまりバズっている感じはしません。もうちょっと人口のあるコミュニティーに流した方が良かったかもしれません。まあ、大々的に宣伝するのは公式サイトとかPlaygroundを整備してからでも良いかもしれません。

今後の方針

LunarMLの改善できる点はたくさんありますが、私の手は2本しかないので、優先順位をつける必要があります。

優先順位を適切に設定するためにも、まずは自分でLunarMLを使ってみる、つまりアプリケーションを書く必要があります。ClutTeXをStandard MLで書き直す作業を進める、などですね。

実用的なことをできるようにするために、JSONやXML等を扱えるようにしたいです。そのためには、lexer generatorやparser generatorがあると良いです。つまり、ML-Lex/ML-ULexやML-YaccなどをLunarMLに移植するか、独自にlexer generatorを書くか、ということになります。これらのコード生成ツールは必ずしもLunarMLにバンドルさせる必要はないかと思いますが、その場合はプロジェクトから手軽に利用できるようにパッケージマネージャーを整備したいです。

Standard ML処理系を作るのは徒労なのか

最近、クソリプおじさんに「SMLは実用的じゃないので駄目w LunarMLは徒労w」みたいなこと(発言内容は正確なものではなくあくまで要約ですが、語尾のヘラヘラした「w」は彼の特徴です)を言われました。まあ、正直言ってStandard MLはイケイケの言語ではありません。30年以上存在するのにこの普及具合なので、「駄目だった」言語と言われても仕方ないかもしれません。

しかし、LunarMLは別にStandard ML標準に「縛られている」わけではありません。既にいくつか拡張機能を検討したり、実装したりしています。こんな記事も書きました:

この記事で挙げたもの以外でも、拡張するアイディアは色々あります。例えば単項マイナスがチルダ ~ なのがイケてないなら、ハイフンマイナス - が前置演算子として使われたら単項マイナスとして解釈する拡張を実装すれば良いのです。Int.toString が単項マイナスをチルダにするのがイケてないなら、ハイフンマイナスを使う別の関数を追加すれば良いのです。例外の捕捉する際に前置するキーワードがないのがイケてないのなら、try をキーワードとして認識する拡張を実装すれば良いのです。メソッド呼び出しがないのがイケてないなら、型に名前空間を紐づける拡張を実装すれば良いのです。

ただ、あまり拡張しすぎるとStandard MLらしさが失われるかもしれません。デフォルトで有効にできない(破壊的な)拡張はいちいち有効にするのが大変かもしれません。その場合は、LunarML言語という独自の言語があることにすれば良いのです。専用の拡張子も作りましょう。Schemeという言語からRacketが誕生したように、PHPからHackが誕生したように、Standard MLからLunarMLが誕生したことにすれば良いのです。

ただ、LunarMLが成熟するまでは拡張機能を前面に出していくのは控えた方が良いかもしれません。具体的には、独自路線を突き進むならばREPLや独自のネイティブコンパイラーは欲しいところです。

将来LunarMLがStandard MLという揺籠から巣立った時に、クソリプおじさんに「あの時俺がああ言ったからLunarMLは方針転換して成功したw」とか言われたくないので、LunarMLの成功はクソリプおじさんの発言とは無関係であることをこの段階で宣言しておきます。

なお、言語の実用性に関しては、表層構文よりもエコシステムの充実具合の方が重要だと私は思います。


読んで頂いてありがとうございました。来年もLunarMLをよろしくお願いします。