SHA1 Hash: | 6de3d8df3a653292a7d25814e07c484bd36fec4a |
---|---|
Date: | 2010-11-28 00:49:30 |
User: | kinaba |
Comment: | reference manual completed |
Timelines: | family | ancestors | descendants | both | trunk |
Downloads: | Tarball | ZIP archive |
Other Links: | files | file ages | manifest |
- branch=trunk inherited from [f65680e1d2]
- sym-trunk inherited from [f65680e1d2]
Modified doc/_common.html from [99ddb75ae65a2432] to [13ff2eea23729a80].
22 22 23 The list of modules globaly used inside Polemy.<br><br> 23 The list of modules globaly used inside Polemy.<br><br> 24 24 25 </td></tr> 25 </td></tr> 26 <tr><td id="docfooter"> 26 <tr><td id="docfooter"> 27 Page was generated with 27 Page was generated with 28 <img src="candydoc/img/candydoc.gif" style="vertical-ali 28 <img src="candydoc/img/candydoc.gif" style="vertical-ali 29 on Sat Nov 27 01:17:56 2010 | 29 on Sat Nov 27 23:29:16 2010 30 30 31 </td></tr> 31 </td></tr> 32 </table> 32 </table> 33 </div> 33 </div> 34 <script> 34 <script> 35 explorer.packageExplorer.addModule("index"); 35 explorer.packageExplorer.addModule("index"); 36 explorer.packageExplorer.addModule("main"); 36 explorer.packageExplorer.addModule("main");
Modified doc/ast.html from [32b42592d934edb1] to [e8eb3b6cfb2de3ee].
590 <script>explorer.outline.decSymbolLevel();</script> 590 <script>explorer.outline.decSymbolLevel();</script> 591 591 592 592 593 </td></tr> 593 </td></tr> 594 <tr><td id="docfooter"> 594 <tr><td id="docfooter"> 595 Page was generated with 595 Page was generated with 596 <img src="candydoc/img/candydoc.gif" style="vertical-ali 596 <img src="candydoc/img/candydoc.gif" style="vertical-ali 597 on Sat Nov 27 21:45:06 2010 | 597 on Sat Nov 27 23:29:16 2010 598 598 599 </td></tr> 599 </td></tr> 600 </table> 600 </table> 601 </div> 601 </div> 602 <script> 602 <script> 603 explorer.packageExplorer.addModule("index"); 603 explorer.packageExplorer.addModule("index"); 604 explorer.packageExplorer.addModule("main"); 604 explorer.packageExplorer.addModule("main");
Modified doc/eval.html from [e2cd33ac962dedb5] to [5a3818f4c9865916].
128 <script>explorer.outline.decSymbolLevel();</script> 128 <script>explorer.outline.decSymbolLevel();</script> 129 129 130 130 131 </td></tr> 131 </td></tr> 132 <tr><td id="docfooter"> 132 <tr><td id="docfooter"> 133 Page was generated with 133 Page was generated with 134 <img src="candydoc/img/candydoc.gif" style="vertical-ali 134 <img src="candydoc/img/candydoc.gif" style="vertical-ali 135 on Sat Nov 27 21:45:07 2010 | 135 on Sat Nov 27 23:29:17 2010 136 136 137 </td></tr> 137 </td></tr> 138 </table> 138 </table> 139 </div> 139 </div> 140 <script> 140 <script> 141 explorer.packageExplorer.addModule("index"); 141 explorer.packageExplorer.addModule("index"); 142 explorer.packageExplorer.addModule("main"); 142 explorer.packageExplorer.addModule("main");
Modified doc/failure.html from [1a82c4c6591961ce] to [7bfc49a4c88d9174].
178 <script>explorer.outline.decSymbolLevel();</script> 178 <script>explorer.outline.decSymbolLevel();</script> 179 179 180 180 181 </td></tr> 181 </td></tr> 182 <tr><td id="docfooter"> 182 <tr><td id="docfooter"> 183 Page was generated with 183 Page was generated with 184 <img src="candydoc/img/candydoc.gif" style="vertical-ali 184 <img src="candydoc/img/candydoc.gif" style="vertical-ali 185 on Sat Nov 27 01:17:58 2010 | 185 on Sat Nov 27 23:29:18 2010 186 186 187 </td></tr> 187 </td></tr> 188 </table> 188 </table> 189 </div> 189 </div> 190 <script> 190 <script> 191 explorer.packageExplorer.addModule("index"); 191 explorer.packageExplorer.addModule("index"); 192 explorer.packageExplorer.addModule("main"); 192 explorer.packageExplorer.addModule("main");
Modified doc/fresh.html from [dd1d4442ef129d46] to [914f41760cdb79ea].
46 <script>explorer.outline.decSymbolLevel();</script> 46 <script>explorer.outline.decSymbolLevel();</script> 47 47 48 48 49 </td></tr> 49 </td></tr> 50 <tr><td id="docfooter"> 50 <tr><td id="docfooter"> 51 Page was generated with 51 Page was generated with 52 <img src="candydoc/img/candydoc.gif" style="vertical-ali 52 <img src="candydoc/img/candydoc.gif" style="vertical-ali 53 on Sat Nov 27 01:17:58 2010 | 53 on Sat Nov 27 23:29:18 2010 54 54 55 </td></tr> 55 </td></tr> 56 </table> 56 </table> 57 </div> 57 </div> 58 <script> 58 <script> 59 explorer.packageExplorer.addModule("index"); 59 explorer.packageExplorer.addModule("index"); 60 explorer.packageExplorer.addModule("main"); 60 explorer.packageExplorer.addModule("main");
Modified doc/index.html from [7883429c0af25534] to [d0516fddd5213f2d].
417 Welcome to Polemy 0.1.0 417 Welcome to Polemy 0.1.0 418 >> 1 + 2 418 >> 1 + 2 419 3 419 3 420 </pre> 420 </pre> 421 この、普通に、数字の 1 は数字の 1 として、2 は 2 として、足し算は足し算として実行するのが、 421 この、普通に、数字の 1 は数字の 1 として、2 は 2 として、足し算は足し算として実行するのが、 422 「<tt>@value</tt> レイヤ」です。 422 「<tt>@value</tt> レイヤ」です。 423 レイヤを明示的に指定するには、<tt>レイヤ名( ... )</tt> という構文を使います。 423 レイヤを明示的に指定するには、<tt>レイヤ名( ... )</tt> という構文を使います。 424 なので、以下のように書いても同じ意味です。 | 424 <font color=red><b>レイヤ指定式</b></font> と読んでいます。 > 425 つまり、さっきのコードは以下のようにも書けます。 425 <pre> 426 <pre> 426 >> @value( 1 + 2 ) 427 >> @value( 1 + 2 ) 427 3 428 3 428 </pre> 429 </pre> 429 他のレイヤで動かしてみましょう。適当に。「<tt>@hoge</tt> レイヤ」で。 430 他のレイヤで動かしてみましょう。適当に。「<tt>@hoge</tt> レイヤ」で。 430 <pre> 431 <pre> 431 >> @hoge( 3 ) 432 >> @hoge( 3 ) ................................................................................................................................................................................ 434 </pre> 435 </pre> 435 <p> 436 <p> 436 エラーになりました。Polemy のインタプリタは、起動時には、<tt>@value</tt> 437 エラーになりました。Polemy のインタプリタは、起動時には、<tt>@value</tt> 437 レイヤでのコードの意味しか知りません。<tt>@hoge</tt> レイヤでは <tt>3</tt> 438 レイヤでのコードの意味しか知りません。<tt>@hoge</tt> レイヤでは <tt>3</tt> 438 というのがどんな意味なのか、わかりません!というエラーが出ています。 439 というのがどんな意味なのか、わかりません!というエラーが出ています。 439 </p> 440 </p> 440 <p> 441 <p> 441 これを教えてあげるためには、<tt>@hoge</tt> レイヤの <font color=red><b>リフト関数</b></font> を定義します。 | 442 これを教えてあげるためには、<tt>@hoge</tt> レイヤの <font color=red><b>リフト関数</b></font> いうもの定義し 442 </p> 443 </p> 443 <pre> 444 <pre> 444 >> @@hoge = fun(x){ x*2 } 445 >> @@hoge = fun(x){ x*2 } 445 (function:1bdc5c0:1ba8580) 446 (function:1bdc5c0:1ba8580) 446 </pre> 447 </pre> 447 <p> 448 <p> > 449 <tt>@hoge</tt> レイヤでは、<tt>1</tt> というコードの意味は <tt>2</tt>、 > 450 <tt>2</tt> というコードの意味は <tt>4</tt>、…、という、全部2倍した意味」を持っていることにします。 448 「<tt>@ レイヤ名 = ...</tt>」文で、 | 451 「<tt>@ レイヤ名 = ...</tt>」 という構文を使います。 > 452 ここには、「<tt>@value</tt> レイヤでの値 <tt>x</tt> は <tt>@hoge</tt> レイヤではどういう意味になるか?」 > 453 を計算して返す関数を登録します。 > 454 これで、Polemy にも、<tt>@hoge</tt> レイヤの意味がわかるようなりました。 449 </p> | 455 </p> 450 <pre> | 456 <pre> 451 [Layers :: Overview] < > 457 >> @hoge( 3 ) 452 | 458 6 453 Polemy's runtime environment has many "layer"s. < 454 Usual execution run in the @value layer. < > 459 </pre> > 460 <p> > 461 では、1+2 を <tt>@hoge</tt> レイヤで動かしてみましょう。 > 462 </p> > 463 <pre> > 464 >> @hoge( 1 + 2 ) > 465 polemy.failure.RuntimeException@C:\Develop\Projects\Polemy\polemy\eval.d(466 > 466 [<REPL>:3:7] only @value layer can call native function: + > 467 [<REPL>:3:7] + > 468 </pre> > 469 <p> > 470 まだエラーですね。これは要するに "+" の意味がわからない、と言っています。 > 471 <font color=red><b>レイヤ指定変数定義式</b></font> で、"+" の意味を教えてあげます。 > 472 </p> > 473 <pre> > 474 >> @hoge "+" = fun(x, y) {x} > 475 (function:182eca0:18435e0) > 476 >> @hoge( 3 + 4 ) 455 | 477 6 > 478 </pre> > 479 <p> > 480 できました。 > 481 </p> > 482 <p> > 483 他の組み込み関数の意味も決めてみましょう。この <tt>@hoge</tt> レイヤでは、 > 484 引き算のつもりで書いたコードが、掛け算になってしまうだ! > 485 </p> > 486 <pre> > 487 >> @hoge "-" = fun(x, y) {x * y} > 488 (function:1b4c6a0:1b4fbe0) 456 >> 1 + 2 | 489 >> @hoge( 5 - 6 ) > 490 polemy.failure.RuntimeException@C:\Develop\Projects\Polemy\polemy\eval.d(469 > 491 [<REPL>:3:24] only @value layer can call native function: * > 492 [<REPL>:3:24] * > 493 [<REPL>:4:8] - > 494 </pre> > 495 <p> > 496 5、の意味は 10 で 6 の意味は 12 なので、10 - 12 と見せかけて掛け算して 120 が返るのだ! > 497 と思いきや、エラーになってしまいました。なぜでしょうそれは、この "-" の定義、 > 498 <code>fun(x, y) {x * y}</code> 自体が、<tt>@hoge</tt> レイヤで実行さるからです。 > 499 掛け算はまだ定義していません。 > 500 </p> > 501 <p> > 502 ここは、「普通の」意味の掛け算を使いたいのです。 > 503 この部分については、<tt>@value</tt> レイヤで計算して欲しい > 504 そんなときは、レイヤ指定式を使います。 > 505 </p> > 506 <pre> > 507 >> @hoge "-" = fun(x, y) {<b>@value(@hoge(x) * @hoge(y))</b>} > 508 (function:1b086c0:1b4fbe0) > 509 >> @hoge( 5 - 6 ) > 510 120 > 511 </pre> > 512 <p> > 513 できました。掛け算は、<tt>@value</tt> レイヤの意味で実行しす。 > 514 各変数は、<tt>@hoge</tt> レイヤで計算された意味を使いますという意味になります。 > 515 </p> > 516 </dd> 457 3 | 517 > 518 <script>explorer.outline.writeEnabled = true;</script> > 519 <dt><span class="decl"> > 520 <span class="currsymbol">関数の自動リフト</span> > 521 <script>explorer.outline.addDecl('関数の自動リフト');</script> > 522 > 523 </span></dt> > 524 <script>explorer.outline.writeEnabled = false;</script> > 525 > 526 <dd><p> > 527 続きです。ちょっと関数を定義してみました。 > 528 </p> > 529 <pre> > 530 >> def twoMinus(x,y,z) { x - y - z } > 531 (function:1b26420:1b4fbe0) 458 >> @value( 1 + 2 ) | 532 >> twoMinus(1,2,3) > 533 -4 > 534 </pre> > 535 <p> > 536 <tt>@value</tt> レイヤで実行すると、当然、1 から 2 と 3 を引て、-4 です。 > 537 </p> > 538 <pre> > 539 >> @hoge( twoMinus(1,2,3) ) > 540 48 > 541 </pre> > 542 <p> > 543 <tt>@hoge</tt> レイヤだと、2 と 4 と 6 を掛け算するので、結果は 48 です。 > 544 </p> > 545 <p> > 546 1, 2, 3 のような値と、+ や - のような組み込み関数について、 > 547 「<tt>@hoge</tt> レイヤでの意味」をレイヤを定義する人が決てやる必要があります。 > 548 でも、それさえ決めれば、あとはプログラム中で自分で定した関数はすべて、 > 549 Polemy 側で自動的にそのレイヤでの意味で実行できるようにります。 > 550 </p> > 551 <p> > 552 レイヤ指定変数定義を使って、変数の意味をそのレイヤでけ上書きして、 > 553 違う意味を与えてやっても構いません。 > 554 </p> > 555 <pre> > 556 >> def twoMinus(x,y,z) { x - y - z } <font color=green># @value レイヤでの > 557 >> @hoge twoMinus(x,y,z) { 21 } <font color=green># @hoge レイでの定 > 558 >> twoMinus(1,2,3) > 559 -4 > 560 >> @hoge( twoMinus(1,2,3) ) > 561 42 > 562 </pre> > 563 <p> > 564 こんな感じで。 > 565 </p> > 566 </dd> 459 3 | 567 > 568 <script>explorer.outline.writeEnabled = true;</script> > 569 <dt><span class="decl"> > 570 <span class="currsymbol">レイヤ指定引数</span> > 571 <script>explorer.outline.addDecl('レイヤ指定引数');</script> 460 | 572 461 Here you can see that @LayerName( Expression ) executes the inner Expression i < 462 the @LayerName layer. Other than @value, one other predefined layer exists: @m < > 573 </span></dt> > 574 <script>explorer.outline.writeEnabled = false;</script> 463 | 575 > 576 <dd><p> > 577 ここまでのサンプルでは、コードを書いた人が、レイヤ指式で明示的にレイヤを切り替えていました。 > 578 <font color=red><b>レイヤ指定引数</b></font> を使うと、ライブラ関数などを書くときに、 > 579 「この関数の第2引数は <tt>@hoge</tt> レイヤで計算して欲し」 > 580 といった指定ができます。 > 581 </p> > 582 <pre> > 583 >> def f(x, y <b>@hoge</b>) { x + @hoge(y) } 464 >> @macro( 1+2 ) | 584 >> f(1, 2) 465 {pos@value:{lineno@value:3, column@value:9, filename@value:<REPL>}, < 466 is@value:app, < 467 args@value:{car@value:{pos@value:{lineno@value:3, column@value:9, filename@v < 468 is@value:int, < 469 data@value:1}, < 470 cdr@value:{ < 471 car@value:{pos@value:{lineno@value:3, column@value:11, filenam < 472 is@value:int, < 473 data@value:2}, < 474 cdr@value:{}}}, < 475 fun@value:{pos@value:{lineno@value:3, column@value:10, filename@value:<REPL < 476 is@value:var, < 477 name@value:+}} < 478 | 585 5 479 (Sorry, this pretty printing is not available on the actual interpreter...) < 480 This evaluates the expression 1+2 in the @macro layer. In this layer, the mean < 481 the program is its abstract syntax tree. < > 586 </pre> > 587 <p> > 588 f の第2引数は、必ず <tt>@hoge</tt> レイヤで解釈されます。 > 589 </p> > 590 <pre> > 591 >> def ff(x, y <b>@hoge @value</b>) { x + @hoge(y) + @value(y) } > 592 >> ff(1, 2) 482 | 593 7 483 You can interleave layers. < 484 The root node of the abstract syntax tree is function "app"lication. < > 594 </pre> > 595 <p> > 596 <tt>@hoge</tt> と <tt>@value</tt> の両方のレイヤで解釈して欲しい、という欲張りな人は、 > 597 レイヤ指定を複数並べて下さい。 > 598 </p> > 599 <p> > 600 なにもレイヤ指定がないと、<font color=red><b>ニュートラルレヤ指定</b></font> と呼ばれ、 > 601 その関数の呼び出し側が解釈されていたレイヤと同じとこにセットされます。 > 602 <tt>let</tt>, <tt>var</tt>, <tt>def</tt> による変数定義も同じで、 > 603 <tt>@hoge x = ...</tt> とレイヤを明示するとそのレイヤでの変数の意味が定義されますが、 > 604 <tt>let x = ...</tt> とレイヤ指定しないで書くと、現在解釈中レイヤに定義、という動作をします。 > 605 </p> > 606 </dd> 485 | 607 486 >> @value(@macro( 1+2 ).is) < 487 app < > 608 <script>explorer.outline.writeEnabled = true;</script> > 609 <dt><span class="decl"> > 610 <span class="currsymbol">ボトムと自動メモ化</span> > 611 <script>explorer.outline.addDecl('ボトムと自動メモ化');</script> 488 | 612 > 613 </span></dt> > 614 <script>explorer.outline.writeEnabled = false;</script> 489 | 615 > 616 <dd><p> > 617 パターンマッチ失敗時と、"..." という式を実行したときと再帰が無限に止まらなくなったとき、 > 618 には、Polemy のコードは実行時エラーで終了します……<tt>@value</tt> レイヤならば。 > 619 </p> > 620 <p> > 621 ユーザー定義レイヤでは、このような時にも実行時エラーならず、 > 622 「<font color=red><b>ボトム</b></font>」という特別な値がリフト数に渡されます。 > 623 組み込みの <tt>_isbot</tt> 関数で、ボトムかどうか判定できます。 > 624 </p> > 625 <p> > 626 「再帰が無限に止まらなくなったとき」は、 > 627 ある引数で呼び出された関数が、return するよりも前にまたじ引数で呼び出されたら、 > 628 ループしていると見なすことで判定しています。 > 629 これを判定する実装の副作用として、ユーザー定義のレイでは、関数は全てメモ化されています。 > 630 つまり、ある関数が2回同じ引数同じ環境で呼び出された、1回目の答えをキャッシュしておいて、 > 631 2回目は計算をせずに即座にキャッシュをひいて答えを返ます。 > 632 </p> > 633 </dd> 490 | 634 491 [Layers :: Defining a new layer] < > 635 <script>explorer.outline.writeEnabled = true;</script> > 636 <dt><span class="decl"> > 637 <span class="currsymbol">まとめ</span> > 638 <script>explorer.outline.addDecl('まとめ');</script> 492 | 639 493 To define a new layer, you should first tell how to "lift" existing values two < 494 Let us define the "@type" layer, where the meaning of programs is their static < > 640 </span></dt> > 641 <script>explorer.outline.writeEnabled = false;</script> 495 | 642 > 643 <dd><p> > 644 まとめると、以下の機能があります。 > 645 </p> > 646 <ul> > 647 <li><tt>@@layer = fun(x) { ... } in ...</tt> で、 > 648 <tt>@value</tt> レイヤの値に別のレイヤでの意味を与えるリト関数を定義</li> > 649 <li><tt>@layer x = ... in ...</tt> で、そのレイヤでのその変数の味を定義</li> > 650 <li>どちらも let/var/def 式の特殊形なので、<tt>@@layer(x) { ... } in ...</tt> などの略記も > 651 <li>式の途中で @layer( ... ) と書くと、レイヤを明示的に切り替えられる</li> > 652 <li>関数の仮引数に fun(x @layer){ ... } とレイヤを指定すると > 653 対応する実引数はそのレイヤで解釈される。</li> > 654 </ul> > 655 <p> > 656 </p> > 657 </dd> > 658 > 659 <script>explorer.outline.writeEnabled = true;</script> > 660 <dt><span class="decl"> > 661 <span class="currsymbol">例</span> > 662 <script>explorer.outline.addDecl('例');</script> > 663 > 664 </span></dt> > 665 <script>explorer.outline.writeEnabled = false;</script> > 666 > 667 <dd><p> > 668 具体的な「値」のかわりに、その「メタ情報」を取り出し、それが処理によってどう変化するか、 > 669 といった情報を解析するのを主な用途として、この機能をってみました。 > 670 プログラムでよく使われる代表的なメタ情報は、「型」で。 > 671 サンプルとしては、sample/type.pmy をご覧下さい。以下、簡単概略。 > 672 </p> > 673 <pre> 496 >> @@type = fun(x) { | 674 @@type = fun(x) { 497 >> if( _isint(x) ) { "int" } else { | 675 if( _isint(x) ) then "int" 498 >> if( _isfun(x) ) { x } else { "unknown" } } < 499 >> } < 500 (Note: polemy REPL may warn some exception here but please ignore) < > 676 else if( _isstr(x) ) then "str" > 677 else if( _isbot(x) ) then "runtime error" > 678 else "type error" 501 | 679 } 502 For simplicity, I here deal only with integers. < 503 _isint is a primitive function of Polemy that checks the dynamic type of a val < 504 For function, leaving it untouched works well for almost all layers. < 505 < > 680 </pre> > 681 <pre> 506 >> @type( 1 ) 682 >> @type( 1 ) 507 int 683 int 508 >> @type( 2 ) 684 >> @type( 2 ) 509 int 685 int 510 >> @type( "foo" ) 686 >> @type( "foo" ) 511 unknown < 512 < > 687 str > 688 </pre> 513 Fine! Let's try to type 1+2. | 689 <p> 514 < > 690 こんな風に、値をメタ情報へ抽象化するのが、リフト関数す。 515 >> @type( 1 + 2 ) | 691 </p> 516 ...\value.d(119): [<REPL>:6:8] only @value layer can call native function | 692 <p> 517 < > 693 型に抽象化したレイヤでの、組み込み関数の意味を考えまょう。 518 Note that the behavior of this program is | 694 "+" は、"int" と "int" を足したら "int" を返す関数です。 519 - run 1+2 in the @type layer < 520 and NOT < > 695 それ以外なら"型エラー"を返します。そういう関数です。 > 696 </p> 521 - run 1+2 in @value and obtain 3 and run 3 in the @type. | 697 <pre> 522 The problem is, the variable "+" is defined only in the @value layer. | 698 var int_int_int = fun (x, y) {@value( 523 To carry out computation in the @type layer. We need to define it also | 699 var tx = @type(x); 524 in the @type layer. | 700 var ty = @type(y); 525 < > 701 if tx=="runtime error" then ty 526 To define some variable in a specific layer, use @LayerName in place of | 702 else if ty=="runtime error" then tx 527 (let|var|def)s. | 703 else if tx=="int" && ty=="int" then "int" > 704 else "type error" > 705 )}; 528 | 706 529 >> let x = 2 < 530 >> @value x = 2 < 531 >> @type x = "int" | 707 @type "+" = int_int_int; 532 >> @hoge x = "fuga" | 708 @type "-" = int_int_int; 533 < > 709 @type "<" = int_int_int; 534 For "+", do it like this. | 710 </pre> 535 < 536 >> @type "+" = fun(x,y) {@value( < 537 >> if( @type(x)=="int" && @type(y)=="int" ) { "int" } else { < 538 >> )} < 539 polemy.value.native!(IntValue,IntValue,IntValue).native.__anonclass24 < 540 < 541 It is just computing the return type from the input type. < 542 Not here that the intended "meaning" of if-then-else is the runtime-branching, < 543 and the meaning of "==" is the value-comparison. These are the @value layer < 544 behavior. So we have defined the function body inside @value layer. < 545 But when we refer the variables x and y, we need its @type layer meaning. < 546 Hence we use @type() there. < 547 < 548 Now we get it. < 549 < > 711 <pre> 550 >> @type( 1 + 2 ) 712 >> @type( 1 + 2 ) 551 int 713 int 552 < > 714 >> @type( 1 + "foo" ) 553 Well, but do we have to define the @type layer meaning for every variables??? | 715 type error 554 No. After you defined @type "+", you'll automatically get the following: | 716 </pre> 555 < 556 >> def double(x) { x + x } < > 717 <p> > 718 「実行時エラーについては、それが起きなければ返すはず型」を計算するという定義に、 557 (function:17e4740:1789720) | 719 ここではしています。さらに(ちょっと手抜きで int 以外を考えていない)if の型定義を考えると、 558 < > 720 こんな雰囲気。 > 721 </p> > 722 <pre> > 723 @type "if" (c, t, e) {@value( > 724 if( @type(c)=="int" || @type(c)=="runtime error" ) then > 725 @type( int_int_int(t(), e()) ) > 726 else > 727 "type error" > 728 )} > 729 </pre> > 730 <p> > 731 関数が自動リフトされるので、フィボナッチ関数の型を調ることができます。 > 732 </p> > 733 <pre> > 734 >> def fib(x) { if x<2 then 1 else fib(x-1)+fib(x-2) }; 559 >> @type( double(123) ) | 735 >> @type( fib(100000000000000) ) 560 int | 736 int 561 < 562 Every user-defined functions are automatically "lift"ed to the appropriate lay < 563 Only primitive functions like "+" requires @yourNewLayer annotation. < 564 < 565 < 566 < 567 [Layers :: neutral-layer] < 568 < 569 let|var|def is to define a variable in the "current" layer. < 570 Not necessary to the @value layer. < 571 < 572 >> @value( let x = 1 in @value(x) ) < 573 1 < 574 < 575 >> @macro( let x = 1 in @value(x) ) | 737 >> def gib(x) { if x<2 then 1 else gib(x-1)+gib(x-"str") }; 576 polemy.failure.RuntimeException: [<REPL>:14:29] variable x not found | 738 >> @type( gib(100000000000000) ) 577 < > 739 type error 578 >> @macro( let x = 1 in @macro(x) ) | 740 </pre> 579 {pos@value:{lineno@value:15, ... | 741 <p> 580 < 581 < 582 < 583 [Layers :: Layered-Parameters] < 584 < > 742 この定義で <tt>fib(100000000000000)</tt> を <tt>@value</tt> レイヤで通に計算して、 > 743 結果の型を見る、というのでは時間がいくらあっても足りせん。 > 744 いったん <tt>@type</tt> のメタ情報の世界に移ってから計算でるのが、レイヤ機能の肝です。 > 745 </p> > 746 <p> 585 >> def foo(x @macro @value) { {fst: x, snd: @macro(x)} } | 747 正確には、この定義で <tt>@type</tt> レイヤに移ると fib("int") を無限に呼び出し続けて止まらなくなるのですが、 586 (function:1730360:1789720) < 587 < > 748 そこは、自動メモ化による再帰検出でボトム値を返す機能よって、うまく止まっています。 > 749 </p> 588 If you annotate function parameters by @LayerNames, when you invoke the functi | 750 <p> 589 < 590 >> foo(1+2) < > 751 それでも上手く型計算ができない(あるいはすごく遅くな)ような複雑な関数があるかもしれません。 > 752 仕方がないので、型情報をアノテーションとしてつけてあることも可能です。 591 {snd@value: {pos@value:{lineno@value:17, column@value:5, filename@value:<REP | 753 </p> 592 is@value:app, arg@value:{... | 754 <pre> 593 /fst@value:3 | 755 @type f = int_int_int; 594 /} | 756 def f(x,y) { ...とても型を計算できないくらい複雑な定義... }; 595 < 596 its corresponding arguments are evaluated in the layer and passed to it. < 597 If you specify multiple layers, the argument expression is run multiple times. < 598 If you do not specify any layer for a parameter, it works in the neutral layer < 599 </pre> 757 </pre> > 758 <p> > 759 これが、レイヤ指定変数定義の典型的な使い道です。 > 760 </p> 600 </dd> 761 </dd> 601 </dl> 762 </dl> 602 <script>explorer.outline.decSymbolLevel();</script> 763 <script>explorer.outline.decSymbolLevel();</script> 603 764 604 765 605 </dd> 766 </dd> 606 767 ................................................................................................................................................................................ 617 <dd><p> 778 <dd><p> 618 Polemy 言語組み込みのレイヤは <code>@value</code> と <code>@macro</code> の二つです。 779 Polemy 言語組み込みのレイヤは <code>@value</code> と <code>@macro</code> の二つです。 619 (内部的にはもういくつかありますが、ユーザから直接は使えません。) 780 (内部的にはもういくつかありますが、ユーザから直接は使えません。) 620 <code>@value</code> は、「普通に」普通のセマンティクスでプログラムを実行するレイヤでした。 781 <code>@value</code> は、「普通に」普通のセマンティクスでプログラムを実行するレイヤでした。 621 <code>@macro</code> は、実は、<code>@value</code> よりも前に実行されるレイヤで、 782 <code>@macro</code> は、実は、<code>@value</code> よりも前に実行されるレイヤで、 622 「プログラムを実行するとその構文木を返す」というセマンティクスで動きます。 783 「プログラムを実行するとその構文木を返す」というセマンティクスで動きます。 623 </p> 784 </p> 624 <pre> < 625 (ここに例) < 626 </pre> < 627 <p> 785 <p> 628 動きとしてはこうです。 786 動きとしてはこうです。 629 </p> 787 </p> 630 <ol> 788 <ol> 631 <li>関数呼び出し時(とトップレベル環境の実行開始時)に、 789 <li>関数呼び出し時(とトップレベル環境の実行開始時)に、 632 まず、<code>@macro</code> レイヤでコードを実行。</li> 790 まず、<code>@macro</code> レイヤでコードを実行。</li> 633 <li>返ってきた構文木を、その関数を呼び出したときのレイヤで実行。</li> 791 <li>返ってきた構文木を、その関数を呼び出したときのレイヤで実行。</li> ................................................................................................................................................................................ 976 1134 977 </span></dt> 1135 </span></dt> 978 <script>explorer.outline.writeEnabled = false;</script> 1136 <script>explorer.outline.writeEnabled = false;</script> 979 1137 980 <dd> <table> <tr><th>_isint</th> <td>(a)</td> <td>a が整数なら 1、でなければ 0</td></tr> 1138 <dd> <table> <tr><th>_isint</th> <td>(a)</td> <td>a が整数なら 1、でなければ 0</td></tr> 981 <tr><th>_isstr</th> <td>(a)</td> <td>a が文字列なら 1、でなければ 0</td></tr> 1139 <tr><th>_isstr</th> <td>(a)</td> <td>a が文字列なら 1、でなければ 0</td></tr> 982 <tr><th>_isfun</th> <td>(a)</td> <td>a が関数なら 1、でなければ 0</td></tr> 1140 <tr><th>_isfun</th> <td>(a)</td> <td>a が関数なら 1、でなければ 0</td></tr> 983 <tr><th>_istable</th> <td>(a)</td> <td>a がテーブルなら 1、でなければ 0</td></tr> | 1141 <tr><th>_istbl</th> <td>(a)</td> <td>a がテーブルなら 1、でなければ 0</td></tr> 984 <tr><th>_isundefined</th> <td>(a)</td> <td>a が未定義値なら 1、でなければ 0</td></tr> | 1142 <tr><th>_isbot</th> <td>(a)</td> <td>a が未定義値なら 1、でなければ 0</td></tr> 985 </table> 1143 </table> 986 </dd> 1144 </dd> 987 </dl> 1145 </dl> 988 <script>explorer.outline.decSymbolLevel();</script> 1146 <script>explorer.outline.decSymbolLevel();</script> 989 1147 990 1148 991 </dd> 1149 </dd> ................................................................................................................................................................................ 994 <script>explorer.outline.decSymbolLevel();</script> 1152 <script>explorer.outline.decSymbolLevel();</script> 995 1153 996 1154 997 </td></tr> 1155 </td></tr> 998 <tr><td id="docfooter"> 1156 <tr><td id="docfooter"> 999 Page was generated with 1157 Page was generated with 1000 <img src="candydoc/img/candydoc.gif" style="vertical-ali 1158 <img src="candydoc/img/candydoc.gif" style="vertical-ali 1001 on Sat Nov 27 22:01:28 2010 | 1159 on Sun Nov 28 00:45:59 2010 1002 1160 1003 </td></tr> 1161 </td></tr> 1004 </table> 1162 </table> 1005 </div> 1163 </div> 1006 <script> 1164 <script> 1007 explorer.packageExplorer.addModule("index"); 1165 explorer.packageExplorer.addModule("index"); 1008 explorer.packageExplorer.addModule("main"); 1166 explorer.packageExplorer.addModule("main");
Modified doc/layer.html from [136da3cf5e90765a] to [e5a65b9174accb2e].
163 <script>explorer.outline.decSymbolLevel();</script> 163 <script>explorer.outline.decSymbolLevel();</script> 164 164 165 165 166 </td></tr> 166 </td></tr> 167 <tr><td id="docfooter"> 167 <tr><td id="docfooter"> 168 Page was generated with 168 Page was generated with 169 <img src="candydoc/img/candydoc.gif" style="vertical-ali 169 <img src="candydoc/img/candydoc.gif" style="vertical-ali 170 on Sat Nov 27 01:17:58 2010 | 170 on Sat Nov 27 23:29:19 2010 171 171 172 </td></tr> 172 </td></tr> 173 </table> 173 </table> 174 </div> 174 </div> 175 <script> 175 <script> 176 explorer.packageExplorer.addModule("index"); 176 explorer.packageExplorer.addModule("index"); 177 explorer.packageExplorer.addModule("main"); 177 explorer.packageExplorer.addModule("main");
Modified doc/lex.html from [4b49ee7344141eea] to [c0949ad2b1503d71].
307 <script>explorer.outline.decSymbolLevel();</script> 307 <script>explorer.outline.decSymbolLevel();</script> 308 308 309 309 310 </td></tr> 310 </td></tr> 311 <tr><td id="docfooter"> 311 <tr><td id="docfooter"> 312 Page was generated with 312 Page was generated with 313 <img src="candydoc/img/candydoc.gif" style="vertical-ali 313 <img src="candydoc/img/candydoc.gif" style="vertical-ali 314 on Sat Nov 27 01:17:59 2010 | 314 on Sat Nov 27 23:29:19 2010 315 315 316 </td></tr> 316 </td></tr> 317 </table> 317 </table> 318 </div> 318 </div> 319 <script> 319 <script> 320 explorer.packageExplorer.addModule("index"); 320 explorer.packageExplorer.addModule("index"); 321 explorer.packageExplorer.addModule("main"); 321 explorer.packageExplorer.addModule("main");
Modified doc/main.html from [0482b340bcdb09a1] to [b09ee9883ce14297].
62 <script>explorer.outline.decSymbolLevel();</script> 62 <script>explorer.outline.decSymbolLevel();</script> 63 63 64 64 65 </td></tr> 65 </td></tr> 66 <tr><td id="docfooter"> 66 <tr><td id="docfooter"> 67 Page was generated with 67 Page was generated with 68 <img src="candydoc/img/candydoc.gif" style="vertical-ali 68 <img src="candydoc/img/candydoc.gif" style="vertical-ali 69 on Sat Nov 27 01:17:56 2010 | 69 on Sat Nov 27 23:29:15 2010 70 70 71 </td></tr> 71 </td></tr> 72 </table> 72 </table> 73 </div> 73 </div> 74 <script> 74 <script> 75 explorer.packageExplorer.addModule("index"); 75 explorer.packageExplorer.addModule("index"); 76 explorer.packageExplorer.addModule("main"); 76 explorer.packageExplorer.addModule("main");
Modified doc/parse.html from [b7809106bd8bbf5f] to [71836dac82f5012f].
56 <script>explorer.outline.decSymbolLevel();</script> 56 <script>explorer.outline.decSymbolLevel();</script> 57 57 58 58 59 </td></tr> 59 </td></tr> 60 <tr><td id="docfooter"> 60 <tr><td id="docfooter"> 61 Page was generated with 61 Page was generated with 62 <img src="candydoc/img/candydoc.gif" style="vertical-ali 62 <img src="candydoc/img/candydoc.gif" style="vertical-ali 63 on Sat Nov 27 01:17:59 2010 | 63 on Sat Nov 27 23:29:20 2010 64 64 65 </td></tr> 65 </td></tr> 66 </table> 66 </table> 67 </div> 67 </div> 68 <script> 68 <script> 69 explorer.packageExplorer.addModule("index"); 69 explorer.packageExplorer.addModule("index"); 70 explorer.packageExplorer.addModule("main"); 70 explorer.packageExplorer.addModule("main");
Modified doc/repl.html from [06b9b45e10860394] to [e0eba4db02a405ab].
156 <script>explorer.outline.decSymbolLevel();</script> 156 <script>explorer.outline.decSymbolLevel();</script> 157 157 158 158 159 </td></tr> 159 </td></tr> 160 <tr><td id="docfooter"> 160 <tr><td id="docfooter"> 161 Page was generated with 161 Page was generated with 162 <img src="candydoc/img/candydoc.gif" style="vertical-ali 162 <img src="candydoc/img/candydoc.gif" style="vertical-ali 163 on Sat Nov 27 01:18:00 2010 | 163 on Sat Nov 27 23:29:21 2010 164 164 165 </td></tr> 165 </td></tr> 166 </table> 166 </table> 167 </div> 167 </div> 168 <script> 168 <script> 169 explorer.packageExplorer.addModule("index"); 169 explorer.packageExplorer.addModule("index"); 170 explorer.packageExplorer.addModule("main"); 170 explorer.packageExplorer.addModule("main");
Modified doc/runtime.html from [05c59f5e4897aa6d] to [91406278395708ce].
42 <script>explorer.outline.decSymbolLevel();</script> 42 <script>explorer.outline.decSymbolLevel();</script> 43 43 44 44 45 </td></tr> 45 </td></tr> 46 <tr><td id="docfooter"> 46 <tr><td id="docfooter"> 47 Page was generated with 47 Page was generated with 48 <img src="candydoc/img/candydoc.gif" style="vertical-ali 48 <img src="candydoc/img/candydoc.gif" style="vertical-ali 49 on Sat Nov 27 01:18:00 2010 | 49 on Sat Nov 27 23:29:21 2010 50 50 51 </td></tr> 51 </td></tr> 52 </table> 52 </table> 53 </div> 53 </div> 54 <script> 54 <script> 55 explorer.packageExplorer.addModule("index"); 55 explorer.packageExplorer.addModule("index"); 56 explorer.packageExplorer.addModule("main"); 56 explorer.packageExplorer.addModule("main");
Modified doc/test.html from [2826fbbbd41fd9fd] to [657ae4105e994a9f].
143 <script>explorer.outline.decSymbolLevel();</script> 143 <script>explorer.outline.decSymbolLevel();</script> 144 144 145 145 146 </td></tr> 146 </td></tr> 147 <tr><td id="docfooter"> 147 <tr><td id="docfooter"> 148 Page was generated with 148 Page was generated with 149 <img src="candydoc/img/candydoc.gif" style="vertical-ali 149 <img src="candydoc/img/candydoc.gif" style="vertical-ali 150 on Sat Nov 27 01:18:02 2010 | 150 on Sat Nov 27 23:29:23 2010 151 151 152 </td></tr> 152 </td></tr> 153 </table> 153 </table> 154 </div> 154 </div> 155 <script> 155 <script> 156 explorer.packageExplorer.addModule("index"); 156 explorer.packageExplorer.addModule("index"); 157 explorer.packageExplorer.addModule("main"); 157 explorer.packageExplorer.addModule("main");
Modified doc/tricks.html from [3a211e8310f22d0a] to [45f9b815486b21bd].
246 <script>explorer.outline.decSymbolLevel();</script> 246 <script>explorer.outline.decSymbolLevel();</script> 247 247 248 248 249 </td></tr> 249 </td></tr> 250 <tr><td id="docfooter"> 250 <tr><td id="docfooter"> 251 Page was generated with 251 Page was generated with 252 <img src="candydoc/img/candydoc.gif" style="vertical-ali 252 <img src="candydoc/img/candydoc.gif" style="vertical-ali 253 on Sat Nov 27 01:18:02 2010 | 253 on Sat Nov 27 23:29:24 2010 254 254 255 </td></tr> 255 </td></tr> 256 </table> 256 </table> 257 </div> 257 </div> 258 <script> 258 <script> 259 explorer.packageExplorer.addModule("index"); 259 explorer.packageExplorer.addModule("index"); 260 explorer.packageExplorer.addModule("main"); 260 explorer.packageExplorer.addModule("main");
Modified doc/value.html from [56bfccf06cb302b1] to [cf9c33eb37eaba08].
259 <script>explorer.outline.decSymbolLevel();</script> 259 <script>explorer.outline.decSymbolLevel();</script> 260 260 261 261 262 </td></tr> 262 </td></tr> 263 <tr><td id="docfooter"> 263 <tr><td id="docfooter"> 264 Page was generated with 264 Page was generated with 265 <img src="candydoc/img/candydoc.gif" style="vertical-ali 265 <img src="candydoc/img/candydoc.gif" style="vertical-ali 266 on Sat Nov 27 01:18:01 2010 | 266 on Sat Nov 27 23:29:22 2010 267 267 268 </td></tr> 268 </td></tr> 269 </table> 269 </table> 270 </div> 270 </div> 271 <script> 271 <script> 272 explorer.packageExplorer.addModule("index"); 272 explorer.packageExplorer.addModule("index"); 273 explorer.packageExplorer.addModule("main"); 273 explorer.packageExplorer.addModule("main");
Modified doc/valueconv.html from [d3b97793d6c2afdf] to [13cec2ea0c3e7792].
98 <script>explorer.outline.decSymbolLevel();</script> 98 <script>explorer.outline.decSymbolLevel();</script> 99 99 100 100 101 </td></tr> 101 </td></tr> 102 <tr><td id="docfooter"> 102 <tr><td id="docfooter"> 103 Page was generated with 103 Page was generated with 104 <img src="candydoc/img/candydoc.gif" style="vertical-ali 104 <img src="candydoc/img/candydoc.gif" style="vertical-ali 105 on Sat Nov 27 01:18:01 2010 | 105 on Sat Nov 27 23:29:23 2010 106 106 107 </td></tr> 107 </td></tr> 108 </table> 108 </table> 109 </div> 109 </div> 110 <script> 110 <script> 111 explorer.packageExplorer.addModule("index"); 111 explorer.packageExplorer.addModule("index"); 112 explorer.packageExplorer.addModule("main"); 112 explorer.packageExplorer.addModule("main");
Modified index.dd from [388d91fa67a7c403] to [33d07971634f6989].
350 <pre> 350 <pre> 351 >> @hoge( 1 + 2 ) 351 >> @hoge( 1 + 2 ) 352 polemy.failure.RuntimeException@C:\Develop\Projects\Polemy\polemy\eval.d(466 352 polemy.failure.RuntimeException@C:\Develop\Projects\Polemy\polemy\eval.d(466 353 [<REPL>:3:7] only @value layer can call native function: + 353 [<REPL>:3:7] only @value layer can call native function: + 354 [<REPL>:3:7] + 354 [<REPL>:3:7] + 355 </pre> 355 </pre> 356 <p> 356 <p> 357 まだエラーですね。これは 実は、リフト関数は | 357 まだエラーですね。これは要するに "+" の意味がわからない、と言っています。 > 358 $(RED $(B レイヤ指定変数定義式)) で、"+" の意味を教えてあげます。 358 </p> 359 </p> 359 <pre> 360 <pre> 360 >> @hoge "+" = fun(x, y) {x} 361 >> @hoge "+" = fun(x, y) {x} > 362 (function:182eca0:18435e0) > 363 >> @hoge( 3 + 4 ) > 364 6 361 </pre> | 365 </pre> > 366 <p> > 367 できました。 > 368 </p> > 369 <p> > 370 他の組み込み関数の意味も決めてみましょう。この <tt>@hoge</tt> レイヤでは、 > 371 引き算のつもりで書いたコードが、掛け算になってしまうだ! > 372 </p> 362 <pre> | 373 <pre> 363 [Layers :: Overview] < 364 < 365 Polemy's runtime environment has many "layer"s. < 366 Usual execution run in the @value layer. < 367 < 368 >> 1 + 2 < 369 3 < 370 >> @value( 1 + 2 ) < 371 3 < 372 < 373 Here you can see that @LayerName( Expression ) executes the inner Expression i | 374 >> @hoge "-" = fun(x, y) {x * y} 374 the @LayerName layer. Other than @value, one other predefined layer exists: @m | 375 (function:1b4c6a0:1b4fbe0) 375 < > 376 >> @hoge( 5 - 6 ) 376 >> @macro( 1+2 ) | 377 polemy.failure.RuntimeException@C:\Develop\Projects\Polemy\polemy\eval.d(469 377 {pos@value:{lineno@value:3, column@value:9, filename@value:<REPL>}, | 378 [<REPL>:3:24] only @value layer can call native function: * 378 is@value:app, | 379 [<REPL>:3:24] * 379 args@value:{car@value:{pos@value:{lineno@value:3, column@value:9, filename@v | 380 [<REPL>:4:8] - 380 is@value:int, | 381 </pre> 381 data@value:1}, < 382 cdr@value:{ < > 382 <p> > 383 5、の意味は 10 で 6 の意味は 12 なので、10 - 12 と見せかけて掛け算して 120 が返るのだ! 383 car@value:{pos@value:{lineno@value:3, column@value:11, filenam | 384 と思いきや、エラーになってしまいました。なぜでしょう。それは、この "-" の定義、 384 is@value:int, | 385 <code>fun(x, y) {x * y}</code> 自体が、<tt>@hoge</tt> レイヤで実行されるからです。 385 data@value:2}, < 386 cdr@value:{}}}, < > 386 掛け算はまだ定義していません。 > 387 </p> 387 fun@value:{pos@value:{lineno@value:3, column@value:10, filename@value:<REPL | 388 <p> 388 is@value:var, < > 389 ここは、「普通の」意味の掛け算を使いたいのです。 389 name@value:+}} | 390 この部分については、<tt>@value</tt> レイヤで計算して欲しい。 390 < > 391 そんなときは、レイヤ指定式を使います。 391 (Sorry, this pretty printing is not available on the actual interpreter...) | 392 </p> 392 This evaluates the expression 1+2 in the @macro layer. In this layer, the mean | 393 <pre> 393 the program is its abstract syntax tree. | 394 >> @hoge "-" = fun(x, y) {$(B @value(@hoge(x) * @hoge(y)))} 394 < > 395 (function:1b086c0:1b4fbe0) 395 You can interleave layers. | 396 >> @hoge( 5 - 6 ) 396 The root node of the abstract syntax tree is function "app"lication. < 397 < 398 >> @value(@macro( 1+2 ).is) < > 397 120 > 398 </pre> > 399 <p> 399 app | 400 できました。掛け算は、<tt>@value</tt> レイヤの意味で実行します。 400 < 401 < 402 < > 401 各変数は、<tt>@hoge</tt> レイヤで計算された意味を使いますという意味になります。 > 402 </p> > 403 )) 403 [Layers :: Defining a new layer] | 404 $(SECTION 関数の自動リフト, $(SECBODY > 405 <p> > 406 続きです。ちょっと関数を定義してみました。 > 407 </p> > 408 <pre> > 409 >> def twoMinus(x,y,z) { x - y - z } > 410 (function:1b26420:1b4fbe0) > 411 >> twoMinus(1,2,3) > 412 -4 > 413 </pre> > 414 <p> > 415 <tt>@value</tt> レイヤで実行すると、当然、1 から 2 と 3 を引て、-4 です。 > 416 </p> > 417 <pre> > 418 >> @hoge( twoMinus(1,2,3) ) > 419 48 > 420 </pre> > 421 <p> > 422 <tt>@hoge</tt> レイヤだと、2 と 4 と 6 を掛け算するので、結果は 48 です。 > 423 </p> > 424 <p> > 425 1, 2, 3 のような値と、+ や - のような組み込み関数について、 > 426 「<tt>@hoge</tt> レイヤでの意味」をレイヤを定義する人が決てやる必要があります。 > 427 でも、それさえ決めれば、あとはプログラム中で自分で定した関数はすべて、 > 428 Polemy 側で自動的にそのレイヤでの意味で実行できるようにります。 > 429 </p> > 430 <p> > 431 レイヤ指定変数定義を使って、変数の意味をそのレイヤでけ上書きして、 > 432 違う意味を与えてやっても構いません。 > 433 </p> > 434 <pre> > 435 >> def twoMinus(x,y,z) { x - y - z } $(D_COMMENT # @value レイヤでの定義) > 436 >> @hoge twoMinus(x,y,z) { 21 } $(D_COMMENT # @hoge レイヤで定義) > 437 >> twoMinus(1,2,3) > 438 -4 > 439 >> @hoge( twoMinus(1,2,3) ) > 440 42 > 441 </pre> > 442 <p> > 443 こんな感じで。 > 444 </p> > 445 )) > 446 $(SECTION レイヤ指定引数, $(SECBODY > 447 <p> > 448 ここまでのサンプルでは、コードを書いた人が、レイヤ指式で明示的にレイヤを切り替えていました。 > 449 $(RED $(B レイヤ指定引数)) を使うと、ライブラリ関数などをくときに、 > 450 「この関数の第2引数は <tt>@hoge</tt> レイヤで計算して欲し」 > 451 といった指定ができます。 > 452 </p> > 453 <pre> > 454 >> def f(x, y $(B @hoge)) { x + @hoge(y) } > 455 >> f(1, 2) 404 | 456 5 405 To define a new layer, you should first tell how to "lift" existing values two < 406 Let us define the "@type" layer, where the meaning of programs is their static < > 457 </pre> > 458 <p> > 459 f の第2引数は、必ず <tt>@hoge</tt> レイヤで解釈されます。 > 460 </p> > 461 <pre> > 462 >> def ff(x, y $(B @hoge @value)) { x + @hoge(y) + @value(y) } > 463 >> ff(1, 2) 407 | 464 7 > 465 </pre> > 466 <p> > 467 <tt>@hoge</tt> と <tt>@value</tt> の両方のレイヤで解釈して欲しい、という欲張りな人は、 > 468 レイヤ指定を複数並べて下さい。 > 469 </p> > 470 <p> > 471 なにもレイヤ指定がないと、$(RED $(B ニュートラルレイヤ指)) と呼ばれ、 > 472 その関数の呼び出し側が解釈されていたレイヤと同じとこにセットされます。 > 473 <tt>let</tt>, <tt>var</tt>, <tt>def</tt> による変数定義も同じで、 > 474 <tt>@hoge x = ...</tt> とレイヤを明示するとそのレイヤでの変数の意味が定義されますが、 > 475 <tt>let x = ...</tt> とレイヤ指定しないで書くと、現在解釈中レイヤに定義、という動作をします。 > 476 </p> > 477 )) > 478 $(SECTION ボトムと自動メモ化, $(SECBODY > 479 <p> > 480 パターンマッチ失敗時と、"..." という式を実行したときと再帰が無限に止まらなくなったとき、 > 481 には、Polemy のコードは実行時エラーで終了します……<tt>@value</tt> レイヤならば。 > 482 </p> > 483 <p> > 484 ユーザー定義レイヤでは、このような時にも実行時エラーならず、 > 485 「$(RED $(B ボトム))」という特別な値がリフト関数に渡されす。 > 486 組み込みの <tt>_isbot</tt> 関数で、ボトムかどうか判定できます。 > 487 </p> > 488 <p> > 489 「再帰が無限に止まらなくなったとき」は、 > 490 ある引数で呼び出された関数が、return するよりも前にまたじ引数で呼び出されたら、 > 491 ループしていると見なすことで判定しています。 > 492 これを判定する実装の副作用として、ユーザー定義のレイでは、関数は全てメモ化されています。 > 493 つまり、ある関数が2回同じ引数同じ環境で呼び出された、1回目の答えをキャッシュしておいて、 > 494 2回目は計算をせずに即座にキャッシュをひいて答えを返ます。 > 495 </p> > 496 )) > 497 $(SECTION まとめ, $(SECBODY > 498 <p> > 499 まとめると、以下の機能があります。 > 500 </p> > 501 <ul> > 502 <li><tt>@@layer = fun(x) { ... } in ...</tt> で、 > 503 <tt>@value</tt> レイヤの値に別のレイヤでの意味を与えるリト関数を定義</li> > 504 <li><tt>@layer x = ... in ...</tt> で、そのレイヤでのその変数の味を定義</li> > 505 <li>どちらも let/var/def 式の特殊形なので、<tt>@@layer(x) { ... } in ...</tt> などの略記も > 506 <li>式の途中で @layer( ... ) と書くと、レイヤを明示的に切り替えられる</li> > 507 <li>関数の仮引数に fun(x @layer){ ... } とレイヤを指定すると > 508 対応する実引数はそのレイヤで解釈される。</li> > 509 </ul> > 510 <p> > 511 </p> > 512 )) > 513 $(SECTION 例, $(SECBODY > 514 <p> > 515 具体的な「値」のかわりに、その「メタ情報」を取り出し、それが処理によってどう変化するか、 > 516 といった情報を解析するのを主な用途として、この機能をってみました。 > 517 プログラムでよく使われる代表的なメタ情報は、「型」で。 > 518 サンプルとしては、sample/type.pmy をご覧下さい。以下、簡単概略。 > 519 </p> > 520 <pre> 408 >> @@type = fun(x) { | 521 @@type = fun(x) { 409 >> if( _isint(x) ) { "int" } else { | 522 if( _isint(x) ) then "int" 410 >> if( _isfun(x) ) { x } else { "unknown" } } < 411 >> } < 412 (Note: polemy REPL may warn some exception here but please ignore) < > 523 else if( _isstr(x) ) then "str" > 524 else if( _isbot(x) ) then "runtime error" > 525 else "type error" 413 | 526 } 414 For simplicity, I here deal only with integers. < 415 _isint is a primitive function of Polemy that checks the dynamic type of a val < 416 For function, leaving it untouched works well for almost all layers. < 417 < > 527 </pre> > 528 <pre> 418 >> @type( 1 ) | 529 >> @type( 1 ) 419 int 530 int 420 >> @type( 2 ) | 531 >> @type( 2 ) 421 int 532 int 422 >> @type( "foo" ) | 533 >> @type( "foo" ) 423 unknown < 424 < > 534 str > 535 </pre> 425 Fine! Let's try to type 1+2. | 536 <p> 426 < > 537 こんな風に、値をメタ情報へ抽象化するのが、リフト関数す。 427 >> @type( 1 + 2 ) | 538 </p> 428 ...\value.d(119): [<REPL>:6:8] only @value layer can call native function | 539 <p> 429 < > 540 型に抽象化したレイヤでの、組み込み関数の意味を考えまょう。 430 Note that the behavior of this program is | 541 "+" は、"int" と "int" を足したら "int" を返す関数です。 431 - run 1+2 in the @type layer < 432 and NOT < > 542 それ以外なら"型エラー"を返します。そういう関数です。 > 543 </p> 433 - run 1+2 in @value and obtain 3 and run 3 in the @type. | 544 <pre> 434 The problem is, the variable "+" is defined only in the @value layer. | 545 var int_int_int = fun (x, y) {@value( 435 To carry out computation in the @type layer. We need to define it also | 546 var tx = @type(x); 436 in the @type layer. | 547 var ty = @type(y); > 548 if tx=="runtime error" then ty > 549 else if ty=="runtime error" then tx > 550 else if tx=="int" && ty=="int" then "int" > 551 else "type error" > 552 )}; 437 553 438 To define some variable in a specific layer, use @LayerName in place of < 439 (let|var|def)s. < 440 < 441 >> let x = 2 < 442 >> @value x = 2 < 443 >> @type x = "int" < 444 >> @hoge x = "fuga" < 445 < 446 For "+", do it like this. < 447 < 448 >> @type "+" = fun(x,y) {@value( | 554 @type "+" = int_int_int; 449 >> if( @type(x)=="int" && @type(y)=="int" ) { "int" } else { "typeerror" } < 450 >> )} < 451 polemy.value.native!(IntValue,IntValue,IntValue).native.__anonclass24 < 452 < 453 It is just computing the return type from the input type. < 454 Not here that the intended "meaning" of if-then-else is the runtime-branching, < 455 and the meaning of "==" is the value-comparison. These are the @value layer < 456 behavior. So we have defined the function body inside @value layer. < 457 But when we refer the variables x and y, we need its @type layer meaning. < 458 Hence we use @type() there. < 459 < 460 Now we get it. < 461 < > 555 @type "-" = int_int_int; > 556 @type "<" = int_int_int; > 557 </pre> > 558 <pre> 462 >> @type( 1 + 2 ) | 559 >> @type( 1 + 2 ) 463 int 560 int 464 < > 561 >> @type( 1 + "foo" ) 465 Well, but do we have to define the @type layer meaning for every variables??? | 562 type error 466 No. After you defined @type "+", you'll automatically get the following: | 563 </pre> 467 < 468 >> def double(x) { x + x } < > 564 <p> > 565 「実行時エラーについては、それが起きなければ返すはず型」を計算するという定義に、 469 (function:17e4740:1789720) | 566 ここではしています。さらに(ちょっと手抜きで int 以外を考えていない)if の型定義を考えると、 470 < > 567 こんな雰囲気。 471 >> @type( double(123) ) | 568 </p> > 569 <pre> > 570 @type "if" (c, t, e) {@value( > 571 if( @type(c)=="int" || @type(c)=="runtime error" ) then > 572 @type( int_int_int(t(), e()) ) > 573 else > 574 "type error" > 575 )} > 576 </pre> > 577 <p> > 578 関数が自動リフトされるので、フィボナッチ関数の型を調ることができます。 > 579 </p> > 580 <pre> > 581 >> def fib(x) { if x<2 then 1 else fib(x-1)+fib(x-2) }; > 582 >> @type( fib(100000000000000) ) 472 int | 583 int 473 < 474 Every user-defined functions are automatically "lift"ed to the appropriate lay < 475 Only primitive functions like "+" requires @yourNewLayer annotation. < 476 < 477 < 478 < 479 [Layers :: neutral-layer] < 480 < 481 let|var|def is to define a variable in the "current" layer. < 482 Not necessary to the @value layer. < 483 < 484 >> @value( let x = 1 in @value(x) ) < 485 1 < 486 < 487 >> @macro( let x = 1 in @value(x) ) | 584 >> def gib(x) { if x<2 then 1 else gib(x-1)+gib(x-"str") }; 488 polemy.failure.RuntimeException: [<REPL>:14:29] variable x not found | 585 >> @type( gib(100000000000000) ) 489 < > 586 type error 490 >> @macro( let x = 1 in @macro(x) ) | 587 </pre> 491 {pos@value:{lineno@value:15, ... | 588 <p> 492 < 493 < 494 < 495 [Layers :: Layered-Parameters] < 496 < > 589 この定義で <tt>fib(100000000000000)</tt> を <tt>@value</tt> レイヤで通に計算して、 > 590 結果の型を見る、というのでは時間がいくらあっても足りせん。 > 591 いったん <tt>@type</tt> のメタ情報の世界に移ってから計算でるのが、レイヤ機能の肝です。 > 592 </p> > 593 <p> 497 >> def foo(x @macro @value) { {fst: x, snd: @macro(x)} } | 594 正確には、この定義で <tt>@type</tt> レイヤに移ると fib("int") を無限に呼び出し続けて止まらなくなるのですが、 498 (function:1730360:1789720) < 499 < > 595 そこは、自動メモ化による再帰検出でボトム値を返す機能よって、うまく止まっています。 > 596 </p> 500 If you annotate function parameters by @LayerNames, when you invoke the functi | 597 <p> 501 < 502 >> foo(1+2) < > 598 それでも上手く型計算ができない(あるいはすごく遅くな)ような複雑な関数があるかもしれません。 > 599 仕方がないので、型情報をアノテーションとしてつけてあることも可能です。 503 {snd@value: {pos@value:{lineno@value:17, column@value:5, filename@value:<REP | 600 </p> 504 is@value:app, arg@value:{... | 601 <pre> 505 /fst@value:3 | 602 @type f = int_int_int; 506 /} | 603 def f(x,y) { ...とても型を計算できないくらい複雑な定義... }; 507 < 508 its corresponding arguments are evaluated in the layer and passed to it. < 509 If you specify multiple layers, the argument expression is run multiple times. < 510 If you do not specify any layer for a parameter, it works in the neutral layer < 511 </pre> 604 </pre> > 605 <p> > 606 これが、レイヤ指定変数定義の典型的な使い道です。 > 607 </p> 512 )) 608 )) 513 ) 609 ) 514 )) 610 )) 515 611 516 612 517 $(SECTION Macro Layers, $(SECBODY 613 $(SECTION Macro Layers, $(SECBODY 518 <p> 614 <p> 519 Polemy 言語組み込みのレイヤは <code>@value</code> と <code>@macro</code> の二つです。 615 Polemy 言語組み込みのレイヤは <code>@value</code> と <code>@macro</code> の二つです。 520 (内部的にはもういくつかありますが、ユーザから直接は使えません。) 616 (内部的にはもういくつかありますが、ユーザから直接は使えません。) 521 <code>@value</code> は、「普通に」普通のセマンティクスでプログラムを実行するレイヤでした。 617 <code>@value</code> は、「普通に」普通のセマンティクスでプログラムを実行するレイヤでした。 522 <code>@macro</code> は、実は、<code>@value</code> よりも前に実行されるレイヤで、 618 <code>@macro</code> は、実は、<code>@value</code> よりも前に実行されるレイヤで、 523 「プログラムを実行するとその構文木を返す」というセマンティクスで動きます。 619 「プログラムを実行するとその構文木を返す」というセマンティクスで動きます。 524 </p> 620 </p> 525 <pre> < 526 (ここに例) < 527 </pre> < 528 <p> 621 <p> 529 動きとしてはこうです。 622 動きとしてはこうです。 530 </p> 623 </p> 531 <ol> 624 <ol> 532 <li>関数呼び出し時(とトップレベル環境の実行開始時)に、 625 <li>関数呼び出し時(とトップレベル環境の実行開始時)に、 533 まず、<code>@macro</code> レイヤでコードを実行。</li> 626 まず、<code>@macro</code> レイヤでコードを実行。</li> 534 <li>返ってきた構文木を、その関数を呼び出したときのレイヤで実行。</li> 627 <li>返ってきた構文木を、その関数を呼び出したときのレイヤで実行。</li>