Diff
Not logged in

Differences From Artifact [b4c241e12eddc95c]:

To Artifact [9e5b0b6dd62ac7dd]:


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