型推論 型推論のある静的型付言語 // 代入 var a = new Test; // var a : Test = new Test; と同等 // ラムダ式 var add = \(x, y) => x + y; // 関数の戻り値 function sub(x, y) { return x – y; }
9.
クロージャ 高階関数でクロージャを返せる inta = 2; function test(b) { return \x => (a + b) * x; } var cl = test(3); // a がグローバル変数のときだけ反映 a = 4; printfln("cl(5) = %d", cl(5));
10.
XML 当初 ASTの直接表記として XML を採用 独自言語の作成に抵抗があった スキーマ名が LLPML しかし XML だろうと独自言語は独自言語 冗長 ヴィジュアル言語のバックエンドを想定 自分自身の記述に到達できず破綻 XML 形式は放棄して独自言語に移行
前方参照 パースは一度でコード生成時に名前解決 パース時に参照解決しない(仮の動的型)コード生成時に参照解決する(静的型) コード生成時に型推論される(静的型) // パース時に構文から Test をクラスと判断 // コード生成時に t の型が決定される var t = new Test; // パース時に構文からメンバの呼び出しと判断 t.test(); // 定義しなければコード生成時にエラー class Test { function test(){} } 前方 後方
13.
サンク サンクとは実行時に生成するラッパ 実行時コード生成(JIT) の一種 引数を値束縛したサンクを delegate とする var add = \(x, y) => x + y; // ラムダ式 var add_2 = \x => add(2, x); // カリー化 // 引数を束縛したサンクを生成 var add_2d = delegate(2, add); // 変数はサンク生成時の値が束縛される int a = 2; var add_a = delegate(a, add);
14.
メンバ関数ポインタ インスタンスメンバへの関数ポインタ 第1 引数に this を束縛したサンク class Test { function test(){} } var f = Test.test; // 静的関数ポインタ printfln("f: %s", typeof(f).Name); var t = new Test; var d = t.test; // delegate(t, Test.test) printfln("d: %s", typeof(d).Name); // 実行結果 // f: function(var:Test) // d: delegate()
15.
値束縛型クロージャ 変数の値をサンクに埋め込むため GC不要 参照型クロージャと挙動が異なる function test() { int a = 2; return \ => printfln("%d", ++a); } var d = test(); // サンクに値束縛されるため何度呼んでも同値 d(); d(); d(); // 実行結果 : 3 3 3