基礎
定数や変数などによって名前が静的に解決可能な場合、識別子はそれを表す。
iden : 777;
iden, TYPE(iden)
$ fl7 'iden : 777; iden, TYPE(iden)'
777
NUMBER
未定義の識別子を記述すると、同じ内容の文字列となる。
iden, TYPE(iden)
$ fl7 'iden, TYPE(iden)'
iden
STRING
未定義の識別子の挙動はPATH
定数によって制御されているが、これを再定義することにより、未定義の識別子の挙動を変えられる。
PATH : pass, name -> name * 5;
iden, TYPE(iden)
$ fl7 'PATH : pass, name -> name * 5; iden, TYPE(iden)'
idenidenidenideniden
STRING
PATH
の呼び出し
未定義の識別子name
を評価したとき、動的名前解決が行われる。
動的名前解決時には、名前解決失敗を表す値pass
を生成し、静的名PATH
で解決される値に対して、PATH(pass; "name")
という関数呼び出しを試みる。
PATH
がpass
を返した場合、名前解決は失敗する。
PATH
がpass
以外の値を返した場合、それを以って名前解決は成功する。
$ fl7 'PATH : pass, name -> name * 2; a'
aa
$ fl7 'PATH : pass, name -> pass; a'
/usr/local/bin/fluorite-7/fluorite-7.js:14191
throw new Error("Can not resolve: name = " + name);
^
Error: Can not resolve: name = a
≪省略≫
マウント演算子
マウント演算子@resolver
は、resolver
によって動的名前解決ができるように変数PATH
を再定義する前置演算子である。
マウント演算子の結合優先度はその他の前置演算子と等しい。
関数のマウント
マウント演算子に関数を与えた場合、関数function
は動的名前解決時にfunction(pass; name)
として呼び出される。
ここで、pass
は名前解決が出来なかった場合に返す値で、name
は解決すべき名前である。
function
がpass
を返した場合、マウント前のPATH
に動的名前解決を委譲する。
@(pass, name -> name * 5);
@(pass, name -> name === "pie" ? 3.14 : pass);
PI, // 定義済みなので円周率が出る
pie, // 未定義かつpieなので3.14が出る
pi, // 未定義かつpieではないので5回繰り返す
$ fl7 '@(pass, name -> name * 5); @(pass, name -> name === "pie" ? 3.14 : pass); PI, pie, pi'
3.141592653589793
3.14
pipipipipi
オブジェクトのマウント
マウント演算子にオブジェクトを与えた場合、解決したい名前でプロパティアクセスを試みる。
プロパティが存在しない場合、マウント前のPATH
に動的名前解決を委譲する。
@{
a : 777;
};
a, // プロパティが存在するので777が出る
b, // プロパティが存在しないのでデフォルトの挙動になる
$ fl7 '@{a : 777}; a, b'
777
b
マウント演算子はスコープに縛られる
マウント演算子は変数宣言と同様の挙動を持っているため、スコープが終わるとその効果は終了する。
(
// ここでマウント
@{
a : 777;
};
// マウントした名前を参照
a
),
// スコープが切れているので通常の挙動に戻った
a,
$ fl7 '(@{a : 777}; a), a'
777
a
STRICT
関数
STRICT
は、2個の引数を取り、常にエラーを投げる関数が格納された定数である。
これをマウントのリゾルバと解釈すると、どんな名前の解決を試みても常にエラーになる挙動になる。
プログラムの先頭で@STRICT;
を行うと、結果的にそのスクリプト内では未定義の識別子が許されない状態になる。
@STRICT;
iden
$ fl7 '@STRICT; iden'
/usr/local/bin/fluorite-7/fluorite-7.js:15062
throw new Error("No such alias: name=" + args[1]);
^
Error: No such alias: name=iden
≪省略≫
@STRICT;
は飽くまで関数のマウントにすぎないため、@STRICT;
の前に行ったマウントは無効になり、@STRICT;
の後に行ったマウントは有効であり、スコープに縛られる。