Differences From Artifact [7883429c0af25534]:
- File
doc/index.html
- 2010-11-27 14:23:54 - part of checkin [005474ba5b] on branch trunk - changed: not to lift _|_ (user: kinaba) [annotate]
To Artifact [d0516fddd5213f2d]:
- File
doc/index.html
- 2010-11-27 15:49:30 - part of checkin [6de3d8df3a] on branch trunk - reference manual completed (user: kinaba) [annotate]
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");