Diff
Not logged in

Differences From Artifact [f78a001ef162c560]:

To Artifact [07bae30af3901ecf]:


8 <p> 8 <p> 9 あとついでに、左のサイドバーの "Package" タブをクリックすると実装のソースのドキュメントが読めます。 9 あとついでに、左のサイドバーの "Package" タブをクリックすると実装のソースのドキュメントが読めます。 10 </p> 10 </p> 11 11 12 $(DDOC_MEMBERS 12 $(DDOC_MEMBERS 13 13 14 $(SECTION Syntax, $(SECBODY 14 $(SECTION Syntax, $(SECBODY 15 < 16 <p> 15 <p> 17 文法について。 16 文法について。 18 字句解析がわりと適当なので、 17 字句解析がわりと適当なので、 19 変数宣言の変数名のところに、数字を変数名として使えて参照できない変数が作れたり、 18 変数宣言の変数名のところに、数字を変数名として使えて参照できない変数が作れたり、 20 予約語は予約語として解釈され得ないところでは普通に変数名として使えちゃったりして、 19 予約語は予約語として解釈され得ないところでは普通に変数名として使えちゃったりして、 21 偶にとんでもない見かけのソースが構文解析通りますが、気にしないで適当に使って下さい。 20 偶にとんでもない見かけのソースが構文解析通りますが、気にしないで適当に使って下さい。 22 </p> 21 </p> ................................................................................................................................................................................ 89 <br/> 88 <br/> 90 パターンマッチも全部 <tt>if</tt> と <tt>==</tt> と <tt>&amp;&amp;</tt> と 89 パターンマッチも全部 <tt>if</tt> と <tt>==</tt> と <tt>&amp;&amp;</tt> と 91 <tt>.</tt> と <tt>.?</tt> を使った関数呼び出し式に書き換えられていますが、 90 <tt>.</tt> と <tt>.?</tt> を使った関数呼び出し式に書き換えられていますが、 92 規則の詳細を説明するのが面倒なので適当に想像して下さい。 91 規則の詳細を説明するのが面倒なので適当に想像して下さい。 93 他の書き換えはこんな感じです。 92 他の書き換えはこんな感じです。 94 </p> 93 </p> 95 <pre> 94 <pre> 96 if (E) then{E} ⇒ if( E, fun(){E}, fun(){} ) | 95 if (E) {E} ⇒ if( E, fun(){E}, fun(){} ) 97 if (E) then{E} else{E} ⇒ if( E, fun(){E}, fun(){E} ) | 96 if (E) {E} else {E} ⇒ if( E, fun(){E}, fun(){E} ) 98 E BINOP E ⇒ BINOP(E, E) | 97 E BINOP E ⇒ BINOP(E, E) 99 { ENTRIES } ⇒ {}{ ENTRIES } | 98 { ENTRIES } ⇒ {}{ ENTRIES } 100 {} ⇒ {}() | 99 {} ⇒ {}() 101 E {ID:E, ...} ⇒ .=(E, ID, E) { ... } | 100 E {ID:E, ...} ⇒ .=(E, ID, E) { ... } 102 </pre> 101 </pre> 103 <p> 102 <p> 104 変数宣言に色々ありますが、<tt>let</tt> と <tt>var</tt> と <tt>def</tt> は同じ扱いで、 103 変数宣言に色々ありますが、<tt>let</tt> と <tt>var</tt> と <tt>def</tt> は同じ扱いで、 105 <tt>in</tt> と <tt>;</tt> は同じ扱いです。つまり 104 <tt>in</tt> と <tt>;</tt> は同じ扱いです。つまり 106 </p> 105 </p> 107 <pre> 106 <pre> 108 let x = E in E 107 let x = E in E ................................................................................................................................................................................ 135 <p> 134 <p> 136 中身が空の関数に何を返させるかは適当です。今はとりあえず適当に文字列返してます。 135 中身が空の関数に何を返させるかは適当です。今はとりあえず適当に文字列返してます。 137 </p> 136 </p> 138 )) 137 )) 139 138 140 $(SECTION 変数のスコープ規則, $(SECBODY 139 $(SECTION 変数のスコープ規則, $(SECBODY 141 <p> 140 <p> 142 NOTE: Theres no "let rec" syntax, but still recursive definition works | 141 基本的には、let によって常識的な感じに変数のスコープがネストします。 > 142 </p> > 143 <pre> > 144 let x=21 in let x=x+x in x $(D_COMMENT # 42) > 145 </pre> > 146 <p> > 147 一方で、"let rec" のような特別な構文はありませんが、 > 148 </p> > 149 <pre> 143 def f(x) { if(x==0){1}else{x*f(x-1)} } in f(10) #=> 3628800 | 150 let f = fun(x) { if(x==0){1}else{x*f(x-1)} } in f(10) $(D_COMMENT # 3628800) 144 yet still the code below also works < 145 def x=21 in def x=x+x in x #=> 42. < 146 The internal scoping mechanism is a little tricky (this is for coping with < 147 the "layer" feature explained below), but I hope that it works as everyone < 148 expects in most cases, as long as you don't use the same-name-variables heavil < > 151 </pre> > 152 <p> > 153 再帰的な関数定義なども、おそらく意図されたとおりに動ます。 > 154 内部の詳細は、諸般の事情により、 > 155 マジカルで破壊的なスコープ規則になっているのですが、 > 156 同名の変数を激しく重ねて使ったりしなければ、 > 157 だいたい自然な動きをすると思います、たぶん、はい。 > 158 </p> > 159 <p> > 160 ひとつだけ不可思議な動きをするのは、以下のケースです > 161 </p> > 162 <pre> > 163 let x = 1 in > 164 let f = fun() {x} in > 165 let x = 2 in > 166 f() $(D_COMMENT # 2!!) > 167 </pre> > 168 <p> > 169 let-in を縦にチェインしたときだけ、同名変数を破壊的に上きします > 170 (再帰関数の定義が"うまく"いっているのはこの上書きのためです)。 > 171 なんでこんなことになっているかというと、 > 172 後で説明する「レイヤ」を使ったときに > 173 <tt>let foo = ... in @lay foo = ... in ...</tt> > 174 で他レイヤに重ね書きするためであります。 149 </p> 175 </p> 150 )) 176 )) 151 | 177 ) 152 )) 178 )) 153 179 154 180 155 181 156 182 157 $(SECTION Basic Features, $(SECBODY 183 $(SECTION Basic Features, $(SECBODY 158 <p> 184 <p> ................................................................................................................................................................................ 183 関数はいわゆる「クロージャ」です。静的スコープで外側の環境にアクセスできます。 209 関数はいわゆる「クロージャ」です。静的スコープで外側の環境にアクセスできます。 184 テーブルはいわゆるプロトタイプチェーンを持っていて、 210 テーブルはいわゆるプロトタイプチェーンを持っていて、 185 自分にないフィールドの場合は親に問い合わせが行く感じになっていますが、 211 自分にないフィールドの場合は親に問い合わせが行く感じになっていますが、 186 フィールドの書き換えがないので、これは特に意味ないかもしれない…。 212 フィールドの書き換えがないので、これは特に意味ないかもしれない…。 187 </p> 213 </p> 188 )) 214 )) 189 $(SECTION パターンマッチ, $(SECBODY 215 $(SECTION パターンマッチ, $(SECBODY 190 pattern matching is also available. Here is an example. | 216 <p> 191 < > 217 適当に実装されたパターンマッチがあります。 > 218 リストの 2n 番目と 2n+1 番目を足して長さを半分にする関数 > 219 </p> > 220 <pre> 192 def adjSum(lst) | 221 def adjSum(lst) 193 { | 222 { 194 case( lst ) | 223 case( lst ) 195 when( {car:x, cdr:{car: y, cdr:z}} ) { {car: x+y, cdr: adjSum(z)} } | 224 when( {car:x, cdr:{car: y, cdr:z}} ) { {car: x+y, cdr: adjSum(z)} } 196 when( {car:x, cdr:{}} ) { {car: x, cdr: {}} } | 225 when( {car:x, cdr:{}} ) { lst } 197 when( {} ) { {} } | 226 when( {} ) { {} } 198 }; < 199 | 227 } 200 It is expanded to a sequence of if-then-elses prefering the first-match. < 201 Note that {a: _} pattern matches all the tables that have the .a field. < 202 It also matches to {a: 123, b: 456} having extra .b field. So, changing the | 228 </pre> 203 order of "when"s in the above code changes the behavior. < > 229 <p> > 230 動かすときには、処理系がそれっぽい if-then-else に展開しています。 > 231 <tt>when</tt> を上から試していって、最初にマッチしたところを実行します。 > 232 </p> > 233 <pre> > 234 PAT ::= "_" $(D_COMMENT # ワイルドード) > 235 | ID $(D_COMMENT # 変数パタン) > 236 | "{" ID ":" PAT "," ... "," ID : PAT "}" $(D_COMMENT # テーブルターン) > 237 | E $(D_COMMENT # 値パター) > 238 </pre> > 239 <p> > 240 変数パターンは常にマッチして、値をその変数に束縛しま。 > 241 ワイルドカードも常にマッチしますが、変数束縛しません > 242 値パターンは、任意の式が書けます。その式を評価した結と <tt>==</tt> ならマッチします。 > 243 外で束縛された変数を値パターンとして配置、は直接はでないので > 244 </p> > 245 <pre> > 246 var x = 123; > 247 case( foo ) > 248 when( {val: x+0} ) { ... } $(D_COMMENT # これは任意の {val:123} とじ) > 249 when( {val: x} ) { ... } $(D_COMMENT # これは任意の foo.?val なら常にマッチ) > 250 </pre> > 251 <p> > 252 適当にちょっと複雑な式にしてやるとよいかも(裏技)。 > 253 </p> > 254 <p> > 255 テーブルパターンは、書かれたキーが全てあればマッチしす。 > 256 <tt>{a: _}</tt> は、<tt>.a</tt> を持ってさえいればマッチするの、 > 257 <tt>{a: 123, b: 456}</tt> なんかにもマッチします。 > 258 なので、リストに対するパターンを書くときには、car/cdr の場合を先に書かないと > 259 <tt>when({})</tt> を上に書くと全部マッチしちゃいます。注意 > 260 </p> 204 )) 261 )) 205 ) 262 ) 206 )) 263 )) 207 264 208 265 209 266 210 267 ................................................................................................................................................................................ 355 is@value:app, arg@value:{... 412 is@value:app, arg@value:{... 356 /fst@value:3 413 /fst@value:3 357 /} 414 /} 358 415 359 its corresponding arguments are evaluated in the layer and passed to it. 416 its corresponding arguments are evaluated in the layer and passed to it. 360 If you specify multiple layers, the argument expression is run multiple times. 417 If you specify multiple layers, the argument expression is run multiple times. 361 If you do not specify any layer for a parameter, it works in the neutral layer 418 If you do not specify any layer for a parameter, it works in the neutral layer > 419 </pre> > 420 )) 362 421 363 422 > 423 $(SECTION Macro Layers, $(SECBODY > 424 <p> > 425 Polemy 言語組み込みのレイヤは <code>@value</code> と <code>@macro</code> の二つです。 > 426 (内部的にはもういくつかありますが、ユーザから直接はえません。) > 427 <code>@value</code> は、「普通に」普通のセマンティクスでプログラムを実行するレイヤでした。 > 428 <code>@macro</code> は、実は、<code>@value</code> よりも前に実行さるレイヤで、 > 429 「プログラムを実行するとその構文木を返す」というセマティクスで動きます。 > 430 </p> > 431 <pre> > 432 (ここに例) > 433 </pre> > 434 <p> > 435 動きとしてはこうです。 > 436 </p> > 437 <ol> > 438 <li>関数呼び出し時(とトップレベル環境の実行開始時)に > 439 まず、<code>@macro</code> レイヤでコードを実行。</li> > 440 <li>返ってきた構文木を、<code>@value</code> レイヤ、 > 441 またはその関数を呼び出したときのレイヤで実行。</li> > 442 </ol> > 443 <p> > 444 <code>@macro</code> レイヤも所詮ただのレイヤですので、 > 445 上で説明した方法で <code>@macro</code> レイヤに関数などを登しておくことで、 > 446 構文木の生成をいじることが可能です。まさにマクロ。 > 447 </p> 364 448 365 [@macro layer] < 366 < > 449 $(DDOC_MEMBERS > 450 $(SECTION 使い方, $(SECBODY > 451 <pre> 367 When function is invoked, it first run in the @macro layer, and after that, 452 When function is invoked, it first run in the @macro layer, and after that, 368 it run in the neutral layer. Here is an example. 453 it run in the neutral layer. Here is an example. 369 454 370 >> @macro twice(x) { x; x } 455 >> @macro twice(x) { x; x } 371 >> def f() { twice(print("Hello")); 999 } 456 >> def f() { twice(print("Hello")); 999 } 372 (function:173b6a0:1789720) 457 (function:173b6a0:1789720) 373 >> f() 458 >> f() ................................................................................................................................................................................ 380 in the @macro layer. Basically what it does is to just construct its syntax t 465 in the @macro layer. Basically what it does is to just construct its syntax t 381 But, since we have defined the "twice" function in the @macro layer, it is 466 But, since we have defined the "twice" function in the @macro layer, it is 382 execute as a function. Resulting syntax tree is 467 execute as a function. Resulting syntax tree is 383 "print("Hello"); print("Hello"); 999" 468 "print("Hello"); print("Hello"); 999" 384 and this is executed on the neutral (in this example, @value) layer. 469 and this is executed on the neutral (in this example, @value) layer. 385 This is the reason why you see two "Hello"s. 470 This is the reason why you see two "Hello"s. 386 471 > 472 [[quote and unquote]] 387 473 > 474 Here is more involved example of code genration. > 475 From "x", it generates "x*x*x*x*x*x*x*x*x*x". > 476 > 477 @macro pow10(x) { > 478 @value( > 479 def pow(x, n) { > 480 if( n == 1 ) { x } > 481 else { > 482 @macro( @value(x) * @value(pow(x,n-1)) ) > 483 } > 484 } > 485 in > 486 pow(@macro(x),10) > 487 ) > 488 }; > 489 > 490 Here, x is a syntax tree but n is an actual integer. If you read carefully, > 491 you should get what is going on. Basically, @macro can be considered like > 492 quasiquoting and @value to be an escape from it. > 493 </pre> > 494 )) > 495 $(SECTION 微妙な挙動, $(SECBODY > 496 <pre> > 497 (rawmacro) レイヤの話 388 498 389 [[limitations]] 499 [[limitations]] 390 500 391 This @macro layer is a very primitive one, and not a perfect macro language. 501 This @macro layer is a very primitive one, and not a perfect macro language. 392 Two major limitations are seen in the following "it" example. 502 Two major limitations are seen in the following "it" example. 393 503 394 >> @macro LetItBe(x, y) { let it = x in y }; 504 >> @macro LetItBe(x, y) { let it = x in y }; ................................................................................................................................................................................ 407 So 517 So 408 518 409 >> LetItBe( 1+2+3, it*it ) 519 >> LetItBe( 1+2+3, it*it ) 410 ...\value.d(173): [<REPL>:24:1] variable LetItBe is not set in layer @value 520 ...\value.d(173): [<REPL>:24:1] variable LetItBe is not set in layer @value 411 521 412 you cannot directly use the macro in the same scope as the definition. 522 you cannot directly use the macro in the same scope as the definition. 413 You need to wrap it up in a function (like the foo() in the above example). 523 You need to wrap it up in a function (like the foo() in the above example). 414 < 415 < 416 < 417 [[quote and unquote]] < 418 < 419 Here is more involved example of code genration. < 420 From "x", it generates "x*x*x*x*x*x*x*x*x*x". < 421 < 422 @macro pow10(x) { < 423 @value( < 424 def pow(x, n) { < 425 if( n == 1 ) { x } < 426 else { < 427 @macro( @value(x) * @value(pow(x,n-1)) ) < 428 } < 429 } < 430 in < 431 pow(@macro(x),10) < 432 ) < 433 }; < 434 < 435 Here, x is a syntax tree but n is an actual integer. If you read carefully, < 436 you should get what is going on. Basically, @macro can be considered like < 437 quasiquoting and @value to be an escape from it. < 438 </pre> 524 </pre> > 525 )) > 526 ) 439 )) 527 )) 440 528 441 529 442 $(SECTION Built-in Primitives, $(SECBODY 530 $(SECTION Built-in Primitives, $(SECBODY 443 <p> 531 <p> 444 組み込み関数・変数の一覧。 532 組み込み関数・変数の一覧。 445 </p> 533 </p>