ATS のファイル名の拡張子である sats と dats の最初の文字はそれぞれ、 単語 static と dynamic に由来しています。 例えば、foo.sats は静的ファイルの名前で、bar.dats は動的ファイルの名前です。 静的ファイルはしばしば SATS ファイルと呼ばれ、通常は関数, 値, データ型宣言, 型定義などのインターフェイス宣言を含んでいます。 SATS ファイルの主要な目的は、静的/動的にかかわらず別々のATSファイルでその中身を共用することにあります。
静的ファイルの典型的な使い方を知るために、シンプルな例を見てみましょう。 まずアッカーマン関数を実装することになったとします。 この関数は原始再帰ではない再帰として有名です。 acker.sats という名前の静的ファイルに、次の関数インターフェイスを宣言します:
静的ファイル内で関数や値のインターフェイス宣言をする際には、 extern キーワード を使わないことに注意してください。 acker.dats という名前の動的ファイルに、次ような実装を書きます:staload "acker.sats" implement acker (m, n) = if m > 0 then if n > 0 then acker (m-1, acker (m, n-1)) else acker (m-1, 1) else n+1 // end of [acker]
acker 関数宣言に対して次のような実装をすることもできます:
staload ACKER = "acker.sats" implement $ACKER.acker (m, n) = acker (m, n) where { fun acker (m: int, n:int): int = if m > 0 then if n > 0 then acker (m-1, acker (m, n-1)) else acker (m-1, 1) else n+1 } // end of [$ACKER.acker]
別のファイル test_acker.dats に次のコードを書いてみましょう:
// #include "share/atspre_staload.hats" // staload "acker.sats" dynload "acker.dats" implement main0 () = () where { // // acker (3, 3) should return 61 // val () = assertloc (acker (3, 3) = 61) } // end of [main0]
次のコマンドラインを実行すれば、 2つのファイル acker.dats と test_acker.dats を簡単にコンパイルできます:
現在のワーキングディレクトリに実行可能ファイル test_acker が生成されるはずです。 次のように分割コンパイルをすることもできます: この分割コンパイルのスタイルは make ユーティリティから呼び出す際に特に有用です。望むなら acker.sats と acker.dats を次のような1つのファイルにまとめることも可能です:
acker3.dats の名前で上記のファイルを作ったとしましょう。 するとテストコードは次のように書けます: ATS の動的ファイルを静的ロードすることが正常であることに注意してください。 実際 ATS の静的ファイルは、関数や値の実装を含まないATSの動的ファイルの単なる特殊形です。