Differences From Artifact [b4c241e12eddc95c]:
- File
index.dd
- 2010-11-24 11:34:03 - part of checkin [c0158c9281] on branch trunk - document updated (user: kinaba) [annotate]
To Artifact [9e5b0b6dd62ac7dd]:
- File
index.dd
- 2010-11-24 12:14:00 - part of checkin [3ae09b8cbf] on branch trunk - changed if-then-else syntax (user: kinaba) [annotate]
65 65
66 $(D_COMMENT # 演算子など) 66 $(D_COMMENT # 演算子など)
67 | "(" E ")" $(D_COMMENT # ただの括弧) 67 | "(" E ")" $(D_COMMENT # ただの括弧)
68 | E BINOP E $(D_COMMENT # 二項演算子いろいろ) 68 | E BINOP E $(D_COMMENT # 二項演算子いろいろ)
69 | E "." ID $(D_COMMENT # テーブルのフィールドアクセス) 69 | E "." ID $(D_COMMENT # テーブルのフィールドアクセス)
70 | E ".?" ID $(D_COMMENT # テーブルにフィールドがあるか否か) 70 | E ".?" ID $(D_COMMENT # テーブルにフィールドがあるか否か)
71 | E "{" ENTRYS "}" $(D_COMMENT # テーブル拡張) 71 | E "{" ENTRYS "}" $(D_COMMENT # テーブル拡張)
72 | "if" "(" E ")" "{" E "}" | 72 | "if" E ("then"|":"|"then" ":") E
73 | "if" "(" E ")" "{" E "}" "else "{" E "}" | 73 | "if" E ("then"|":"|"then" ":") E "else" ":"? E
74 74
75 $(D_COMMENT # パターンマッチ) 75 $(D_COMMENT # パターンマッチ)
76 | "case" "(" E ")" ("when" "(" PATTERN ")" "{" E "}")* | 76 | "case" E ("when" PATTERN ":" E )*
77 77
78 where PATTERN ::= 式がだいたいなんでも書ける気がする 78 where PATTERN ::= 式がだいたいなんでも書ける気がする
79 79
80 $(D_COMMENT # レイヤ指定実行) 80 $(D_COMMENT # レイヤ指定実行)
81 | LAYER "(" E ")" 81 | LAYER "(" E ")"
82 </pre> 82 </pre>
83 )) 83 ))
................................................................................................................................................................................
88 <br/> 88 <br/>
89 パターンマッチも全部 <tt>if</tt> と <tt>==</tt> と <tt>&&</tt> と 89 パターンマッチも全部 <tt>if</tt> と <tt>==</tt> と <tt>&&</tt> と
90 <tt>.</tt> と <tt>.?</tt> を使った関数呼び出し式に書き換えられていますが、 90 <tt>.</tt> と <tt>.?</tt> を使った関数呼び出し式に書き換えられていますが、
91 規則の詳細を説明するのが面倒なので適当に想像して下さい。 91 規則の詳細を説明するのが面倒なので適当に想像して下さい。
92 他の書き換えはこんな感じです。 92 他の書き換えはこんな感じです。
93 </p> 93 </p>
94 <pre> 94 <pre>
95 if (E) {E} ⇒ if( E, fun(){E}, fun(){} ) | 95 if E then E ⇒ if( E, fun(){E}, fun(){} )
96 if (E) {E} else {E} ⇒ if( E, fun(){E}, fun(){E} ) | 96 if E then E else E ⇒ if( E, fun(){E}, fun(){E} )
97 E BINOP E ⇒ BINOP(E, E) 97 E BINOP E ⇒ BINOP(E, E)
98 { ENTRIES } ⇒ {}{ ENTRIES } 98 { ENTRIES } ⇒ {}{ ENTRIES }
99 {} ⇒ {}() 99 {} ⇒ {}()
100 E {ID:E, ...} ⇒ .=(E, ID, E) { ... } 100 E {ID:E, ...} ⇒ .=(E, ID, E) { ... }
101 </pre> 101 </pre>
102 <p> 102 <p>
103 変数宣言に色々ありますが、<tt>let</tt> と <tt>var</tt> と <tt>def</tt> は同じ扱いで、 103 変数宣言に色々ありますが、<tt>let</tt> と <tt>var</tt> と <tt>def</tt> は同じ扱いで、
................................................................................................................................................................................
109 def x = E in E 109 def x = E in E
110 let x = E ; E 110 let x = E ; E
111 var x = E ; E 111 var x = E ; E
112 def x = E ; E 112 def x = E ; E
113 </pre> 113 </pre>
114 <p> 114 <p>
115 以上のどれも同じ意味なので、なんとなく関数型っぽく書きたい気分の日は <tt>let in</tt> を、 115 以上のどれも同じ意味なので、なんとなく関数型っぽく書きたい気分の日は <tt>let in</tt> を、
116 手続き型っぽく書きたい気分の日は <tt>var ;</tt> を使うとよいしょう。 | 116 手続き型っぽく書きたい気分の日は <tt>var ;</tt> を使うとよい思います。
> 117 <tt>if then else</tt> も微妙にコロンがあったりなかったりバリーションがありますが好みで使います。
117 </p> 118 </p>
118 <p> 119 <p>
119 関数を宣言するときは、<tt>fun</tt> や <tt>λ</tt> を省略できます。 120 関数を宣言するときは、<tt>fun</tt> や <tt>λ</tt> を省略できます。
120 以下の書き換えが行われます。 121 以下の書き換えが行われます。
121 </p> 122 </p>
122 <pre> 123 <pre>
123 def f( ARGS ) { E }; E ⇒ def f = fun(ARGS){E}; E 124 def f( ARGS ) { E }; E ⇒ def f = fun(ARGS){E}; E
................................................................................................................................................................................
143 <pre> 144 <pre>
144 let x=21 in let x=x+x in x $(D_COMMENT # 42) 145 let x=21 in let x=x+x in x $(D_COMMENT # 42)
145 </pre> 146 </pre>
146 <p> 147 <p>
147 一方で、"let rec" のような特別な構文はありませんが、 148 一方で、"let rec" のような特別な構文はありませんが、
148 </p> 149 </p>
149 <pre> 150 <pre>
150 let f = fun(x) { if(x==0){1}else{x*f(x-1)} } in f(10) $(D_COMMENT # 3628800) | 151 let f = fun(x) { if x==0 then 1 else x*f(x-1) } in f(10) $(D_COMMENT # 36288
151 </pre> 152 </pre>
152 <p> 153 <p>
153 再帰的な関数定義なども、おそらく意図されたとおりに動きます。 154 再帰的な関数定義なども、おそらく意図されたとおりに動きます。
154 内部の詳細は、諸般の事情により、 155 内部の詳細は、諸般の事情により、
155 マジカルで破壊的なスコープ規則になっているのですが、 156 マジカルで破壊的なスコープ規則になっているのですが、
156 同名の変数を激しく重ねて使ったりしなければ、 157 同名の変数を激しく重ねて使ったりしなければ、
157 だいたい自然な動きをすると思います、たぶん、はい。 158 だいたい自然な動きをすると思います、たぶん、はい。
................................................................................................................................................................................
222 <p> 223 <p>
223 適当に実装されたパターンマッチがあります。 224 適当に実装されたパターンマッチがあります。
224 リストの 2n 番目と 2n+1 番目を足して長さを半分にする関数: 225 リストの 2n 番目と 2n+1 番目を足して長さを半分にする関数:
225 </p> 226 </p>
226 <pre> 227 <pre>
227 def adjSum(lst) 228 def adjSum(lst)
228 { 229 {
229 case( lst ) | 230 case lst
230 when( {car:x, cdr:{car: y, cdr:z}} ) { {car: x+y, cdr: adjSum(z)} } | 231 when {car:x, cdr:{car: y, cdr:z}}: {car: x+y, cdr: adjSum(z)}
231 when( {car:x, cdr:{}} ) { lst } | 232 when {car:x, cdr:{}}: lst
232 when( {} ) { {} } | 233 when {}: {}
233 } 234 }
234 </pre> 235 </pre>
235 <p> 236 <p>
236 動かすときには、処理系がそれっぽい if-then-else に展開しています。 237 動かすときには、処理系がそれっぽい if-then-else に展開しています。
237 <tt>when</tt> を上から試していって、最初にマッチしたところを実行します。 238 <tt>when</tt> を上から試していって、最初にマッチしたところを実行します。
238 </p> 239 </p>
239 <pre> 240 <pre>
................................................................................................................................................................................
246 変数パターンは常にマッチして、値をその変数に束縛します。 247 変数パターンは常にマッチして、値をその変数に束縛します。
247 ワイルドカードも常にマッチしますが、変数束縛しません。 248 ワイルドカードも常にマッチしますが、変数束縛しません。
248 値パターンは、任意の式が書けます。その式を評価した結果と <tt>==</tt> ならマッチします。 249 値パターンは、任意の式が書けます。その式を評価した結果と <tt>==</tt> ならマッチします。
249 外で束縛された変数を値パターンとして配置、は直接はできないので 250 外で束縛された変数を値パターンとして配置、は直接はできないので
250 </p> 251 </p>
251 <pre> 252 <pre>
252 var x = 123; 253 var x = 123;
253 case( foo ) | 254 case foo
254 when( {val: x+0} ) { ... } $(D_COMMENT # これは任意の {val:123} と同じ) | 255 when {val: x+0}: ... $(D_COMMENT # これは {val:123} と同じ)
255 when( {val: x} ) { ... } $(D_COMMENT # これは任意の foo.?val なら常にマッチ) | 256 when {val: x}: ... $(D_COMMENT # これは任意の foo.?val なら常にマッチ)
256 </pre> 257 </pre>
257 <p> 258 <p>
258 適当にちょっと複雑な式にしてやるとよいかも(裏技)。 259 適当にちょっと複雑な式にしてやるとよいかも(裏技)。
259 </p> 260 </p>
260 <p> 261 <p>
261 テーブルパターンは、書かれたキーが全てあればマッチします。 262 テーブルパターンは、書かれたキーが全てあればマッチします。
262 <tt>{a: _}</tt> は、<tt>.a</tt> を持ってさえいればマッチするので、 263 <tt>{a: _}</tt> は、<tt>.a</tt> を持ってさえいればマッチするので、
263 <tt>{a: 123, b: 456}</tt> なんかにもマッチします。 264 <tt>{a: 123, b: 456}</tt> なんかにもマッチします。
264 なので、リストに対するパターンを書くときには、car/cdr の場合を先に書かないと 265 なので、リストに対するパターンを書くときには、car/cdr の場合を先に書かないと
265 <tt>when({})</tt> を上に書くと全部マッチしちゃいます。注意。 | 266 <tt>when {}</tt> を上に書くと全部マッチしちゃいます。注意。
266 </p> 267 </p>
267 )) 268 ))
268 ) 269 )
269 )) 270 ))
270 271
271 272
272 273