lambda day

速い日記schemeによるlambda計算の課題のことが書いてあったので、締め切りが実は明日までだったことを思い出す。OCamlで書いた方が楽そうだったが、パーサー書くのも入出力を書くのも面土井。といことで、速い人のevalテクニックをパクらせてもらった。まぁ、便利というか何というか。。。
ところで、処理系どうしようかと思ったらcygwinにguileがあったので入れてみたわけだが、どうやらevalの定義が違うんだかなんだかで動かない。うーん、よくわからん。しょうがないのでgambit。tera term越しに使うとナゼか何も出力されない。原因不明。ふつうにコマンドプロンプト越しだと問題なし。
さて、昨年のインタプリタぶりだから1年ぶりか。すべてわすれてる。defineもcondもbeginも忘れてる。quoteとかevalとか。O氏が『書いてあるとおりに書いたら動いた』といっていたが、ホントにそんな感じだ。コンパイラ係としては、パースからK正規化まで終わっているので、α変換してからβ変換(インライン展開)するだけ。本体は数十行ですみますね。まぁ、evalのおかげなんですが。
ところで、β変換の順番適当にすると異常に遅い。適当にいじっていたら、突然速くなったからよかったが、ちゃんと止まるかどうかとか検証してないし、する気も。。。FACT動いたからいいか。にしても、match文と型推論は偉大ですね。つーか、やっぱり()は読みづらいよ。

追記

実はevalを使わなくてもいいことが分かった。というか、OCamlで書きつつ思ったのは、要はquoteのなかで部分的にunquoteできれば事足りると。で、ぐぐったらback quoteなる式があることが判明。'の代わりに`を使って、unquoteしたいところの前に,をつければいいらしい。
今まで自由変数にぶち当たったらevalしていた。つまり、

(define ONE (calc '(SUCC ZERO)))

ってかいて、自由変数なSUCCとZEROをevalしていたが、その代わりに、

(define ONE (calc `(,SUCC ,ZERO))

ってかくと、かいた時点でSUCCとZEROは展開されて、その後計算する寸法。