PolyMLの依存関係管理

Poly/MLはREPLとしてもコンパイラとしても使うことのできるSML処理系です。
64bit環境に対応した処理系でもあるので、そういった意味でお手軽な場合も多そうですね。


ここではPolyMLのREPLでコードを読み込む方法を紹介します。

use

とりあえず use は備えています。指定したファイルの内容を直接replに入力したように動きます。

> val use;
val it = fn : use : string -> unit
> use "Sample1.sml";
structure Sample1 : sig val f : unit -> unit end
val it = (): unit
>

PolyML.make

本題。必要なデータ/ファイルだけを(再)読み込みする機能。
SML/NJのCM*1(の一分)に相当する機能がREPLに組み込まれています。

単一ファイルから成るオブジェクト

まず Sample1.sml というファイルがある場合、

$ ls
Sample1.sml
$ cat Sample1.sml
structure Sample1 =
struct
  fun f () = print "Sample1.f\n"
end

以下のように PolyML.make "structure/signature/functor名" を評価すると、対応するファイルを読み込みます。

> PolyML.make "Sample1"; (* structure名を指定 *)
Making Sample1
Created structure Sample1
structure Sample1 : sig val f : unit -> unit end
val it = (): unit
> Sample1.f();           (* 読み込まれている *)
Sample1.f
val it = (): unit
> PolyML.make "Sample1"; (* もう一度評価しても *)
val it = (): unit        (* 必要無いのでリコンパイルされない *)

前回の評価以降に変更されたファイルのみ読み込むので、二度連続でmakeしても余計なコンパイルは発生しません。
また、指定したファイルから公開される他の名前のオブジェクト*2も同時に公開されます。

複数ファイルから成るオブジェクト

以下のように structure Sample2 が Sample3 に依存している場合、

structure Sample2 =
struct
  fun f () = Sample3.f "Sample2.f"
end

structure名に対応したディレクトリ内に ml_bind.ML*3 というファイル名で実装を提供します。

$ ls Sample2/
ml_bind.ML  Sample3.sml # ml_bind.ML 内で Sample2 が定義されている


実際に読み込む場合は Sample1 の時と同じくstructure名を指定するだけです。

> PolyML.make "Sample2";
Making Sample2
Making Sample3
Created structure Sample3
structure Sample3 : sig val f : string -> unit end
Created structure Sample2
structure Sample2 : sig val f : unit -> unit end
val it = (): unit

出典

Chapter 7: The Poly/ML Make System
公式ドキュメントですが、上で紹介した機能以外はもう提供されていないみたいです。

メモ

ビルドに際して複雑なことは出来なさそうですが、CMやMLBasisより覚えることが少なくお手軽なので64bit環境しか手元に無い人はPolyMLに堕とすをお勧めするのもいいかも知れません(^^)

*1:CompileManager

*2:structure/signature/functor

*3:なんだこの名前…