Differences From Artifact [49fcca2a72fbb7a0]:
- File
doc/index.html
- 2010-11-24 11:34:03 - part of checkin [c0158c9281] on branch trunk - document updated (user: kinaba) [annotate]
To Artifact [f03a1357a018cf8a]:
- File
doc/index.html
- 2010-11-24 12:14:00 - part of checkin [3ae09b8cbf] on branch trunk - changed if-then-else syntax (user: kinaba) [annotate]
114 114
115 115 <font color=green># 演算子など</font>
116 116 | "(" E ")" <font color=green># ただの括弧</font>
117 117 | E BINOP E <font color=green># 二項演算子いろいろ</font>
118 118 | E "." ID <font color=green># テーブルのフィールドアクセス</font>
119 119 | E ".?" ID <font color=green># テーブルにフィールドがあるか否か</font>
120 120 | E "{" ENTRYS "}" <font color=green># テーブル拡張</font>
121 - | "if" "(" E ")" "{" E "}"
122 - | "if" "(" E ")" "{" E "}" "else "{" E "}"
121 + | "if" E ("then"|":"|"then" ":") E
122 + | "if" E ("then"|":"|"then" ":") E "else" ":"? E
123 123
124 124 <font color=green># パターンマッチ</font>
125 - | "case" "(" E ")" ("when" "(" PATTERN ")" "{" E "}")*
125 + | "case" E ("when" PATTERN ":" E )*
126 126
127 127 where PATTERN ::= 式がだいたいなんでも書ける気がする
128 128
129 129 <font color=green># レイヤ指定実行</font>
130 130 | LAYER "(" E ")"
131 131 </pre>
132 132 </dd>
................................................................................
145 145 <br/>
146 146 パターンマッチも全部 <tt>if</tt> と <tt>==</tt> と <tt>&&</tt> と
147 147 <tt>.</tt> と <tt>.?</tt> を使った関数呼び出し式に書き換えられていますが、
148 148 規則の詳細を説明するのが面倒なので適当に想像して下さい。
149 149 他の書き換えはこんな感じです。
150 150 </p>
151 151 <pre>
152 - if (E) {E} ⇒ if( E, fun(){E}, fun(){} )
153 - if (E) {E} else {E} ⇒ if( E, fun(){E}, fun(){E} )
152 + if E then E ⇒ if( E, fun(){E}, fun(){} )
153 + if E then E else E ⇒ if( E, fun(){E}, fun(){E} )
154 154 E BINOP E ⇒ BINOP(E, E)
155 155 { ENTRIES } ⇒ {}{ ENTRIES }
156 156 {} ⇒ {}()
157 157 E {ID:E, ...} ⇒ .=(E, ID, E) { ... }
158 158 </pre>
159 159 <p>
160 160 変数宣言に色々ありますが、<tt>let</tt> と <tt>var</tt> と <tt>def</tt> は同じ扱いで、
................................................................................
166 166 def x = E in E
167 167 let x = E ; E
168 168 var x = E ; E
169 169 def x = E ; E
170 170 </pre>
171 171 <p>
172 172 以上のどれも同じ意味なので、なんとなく関数型っぽく書きたい気分の日は <tt>let in</tt> を、
173 -手続き型っぽく書きたい気分の日は <tt>var ;</tt> を使うとよいでしょう。
173 +手続き型っぽく書きたい気分の日は <tt>var ;</tt> を使うとよいと思います。
174 +<tt>if then else</tt> も微妙にコロンがあったりなかったりバリエーションがありますが好みで使います。
174 175 </p>
175 176 <p>
176 177 関数を宣言するときは、<tt>fun</tt> や <tt>λ</tt> を省略できます。
177 178 以下の書き換えが行われます。
178 179 </p>
179 180 <pre>
180 181 def f( ARGS ) { E }; E ⇒ def f = fun(ARGS){E}; E
................................................................................
208 209 <pre>
209 210 let x=21 in let x=x+x in x <font color=green># 42</font>
210 211 </pre>
211 212 <p>
212 213 一方で、"let rec" のような特別な構文はありませんが、
213 214 </p>
214 215 <pre>
215 - let f = fun(x) { if(x==0){1}else{x*f(x-1)} } in f(10) <font color=green># 3628800</font>
216 + let f = fun(x) { if x==0 then 1 else x*f(x-1) } in f(10) <font color=green># 3628800</font>
216 217 </pre>
217 218 <p>
218 219 再帰的な関数定義なども、おそらく意図されたとおりに動きます。
219 220 内部の詳細は、諸般の事情により、
220 221 マジカルで破壊的なスコープ規則になっているのですが、
221 222 同名の変数を激しく重ねて使ったりしなければ、
222 223 だいたい自然な動きをすると思います、たぶん、はい。
................................................................................
315 316 <dd><p>
316 317 適当に実装されたパターンマッチがあります。
317 318 リストの 2n 番目と 2n+1 番目を足して長さを半分にする関数:
318 319 </p>
319 320 <pre>
320 321 def adjSum(lst)
321 322 {
322 - case( lst )
323 - when( {car:x, cdr:{car: y, cdr:z}} ) { {car: x+y, cdr: adjSum(z)} }
324 - when( {car:x, cdr:{}} ) { lst }
325 - when( {} ) { {} }
323 + case lst
324 + when {car:x, cdr:{car: y, cdr:z}}: {car: x+y, cdr: adjSum(z)}
325 + when {car:x, cdr:{}}: lst
326 + when {}: {}
326 327 }
327 328 </pre>
328 329 <p>
329 330 動かすときには、処理系がそれっぽい if-then-else に展開しています。
330 331 <tt>when</tt> を上から試していって、最初にマッチしたところを実行します。
331 332 </p>
332 333 <pre>
................................................................................
339 340 変数パターンは常にマッチして、値をその変数に束縛します。
340 341 ワイルドカードも常にマッチしますが、変数束縛しません。
341 342 値パターンは、任意の式が書けます。その式を評価した結果と <tt>==</tt> ならマッチします。
342 343 外で束縛された変数を値パターンとして配置、は直接はできないので
343 344 </p>
344 345 <pre>
345 346 var x = 123;
346 - case( foo )
347 - when( {val: x+0} ) { ... } <font color=green># これは任意の {val:123} と同じ</font>
348 - when( {val: x} ) { ... } <font color=green># これは任意の foo.?val なら常にマッチ</font>
347 + case foo
348 + when {val: x+0}: ... <font color=green># これは {val:123} と同じ</font>
349 + when {val: x}: ... <font color=green># これは任意の foo.?val なら常にマッチ</font>
349 350 </pre>
350 351 <p>
351 352 適当にちょっと複雑な式にしてやるとよいかも(裏技)。
352 353 </p>
353 354 <p>
354 355 テーブルパターンは、書かれたキーが全てあればマッチします。
355 356 <tt>{a: _}</tt> は、<tt>.a</tt> を持ってさえいればマッチするので、
356 357 <tt>{a: 123, b: 456}</tt> なんかにもマッチします。
357 358 なので、リストに対するパターンを書くときには、car/cdr の場合を先に書かないと
358 -<tt>when({})</tt> を上に書くと全部マッチしちゃいます。注意。
359 +<tt>when {}</tt> を上に書くと全部マッチしちゃいます。注意。
359 360 </p>
360 361 </dd>
361 362 </dl>
362 363 <script>explorer.outline.decSymbolLevel();</script>
363 364
364 365
365 366 </dd>
................................................................................
800 801 <script>explorer.outline.decSymbolLevel();</script>
801 802
802 803
803 804 </td></tr>
804 805 <tr><td id="docfooter">
805 806 Page was generated with
806 807 <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px">
807 - on Wed Nov 24 20:33:08 2010
808 + on Wed Nov 24 21:12:48 2010
808 809
809 810 </td></tr>
810 811 </table>
811 812 </div>
812 813 <script>
813 814 explorer.packageExplorer.addModule("index");
814 815 explorer.packageExplorer.addModule("main");