言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

最近やっている事

特にこれといってないけどしばらく書いてないので記録のために最近やってる事を書く。

最近ずっと ActionScript VM (AVM2) のためのアセンブラを書いている。言語は色々迷ったけど、友人 D 氏の薦めで PLT Scheme にした。一番の決め手はドキュメントがとても良く出来ているのと、サンプルコードが沢山あるので私のような Scheme 初心者には丁度よいかもと思ったからだ。今の所いい感じだけど、唯一の不満はエラー表示がおかしい所。関数の途中でエラーが起こっても関数の先頭の行が報告される事があって、こんなメジャーな実装なのにこんなにヘボいのかとびっくりした。

あとで独自言語に移植する予定なので、出来るだけ便利機能は使わない縛りで行っている。例えば構造体もパターンマッチも使わず、とことん car と cdr で頑張っている。SICP にそういうコードが沢山出てくるので参考になる。本当は末尾再帰最適化も使えないのだが、Scheme で末尾再帰しないでループを作る方法が分からなかったので気にせず使っている。

Scheme というと、関数型言語としては胡散臭いと思っていたんだけど、わりと関数型っぽく書ける事が分かった。今の所 port で入出力する以外で副作用を使っていない。特に今回 CPS (継続渡し形式) というのを初めて使った。CPS は関数が多値を返す時。例えばシンボルを辞書に副作用無しで登録して行く時、インデックスと登録後の辞書を返す時なんかに有効で、リストで二つの値を組み合わせて返していた場合と比べて格段にきれいに書ける。Haskell なんかだとパターンマッチがあるからタプルで返しても見た目抵抗ないけど、Scheme の場合 car と cdr を駆使する心理的重圧感は相当な物だ。CPS を使うと妙な障壁が無くなってプログラムが流れるように美しくなった。でも効率が悪そうなので結局あとで副作用を使って書き直す羽目になるかも知れないけど、とりあえず CPS が役に立つ事が分かって良かった。

アセンブラを書くくらい一週間もあれば終わるだろうと思ったが、思いのほか苦労している。最初複雑なネームスペースの扱いを理解するのに苦労して、インスタンスとクラスとスクリプトというややこしい用語に苦労して(AVM2 では、クラスのメンバをインスタンスと言って、スタティックメンバをクラスと言って、その他初期化コードをスクリプトと呼ぶ)、今バイトコードを組み立てるのに苦労している。というのも、AVM2 はスタックの最大深さやレジスタ数なんかの情報があらかじめ必要で、命令列を全部舐めてどの命令がいくつスタックを食うかというのを全部調べないといけないからだ。

仕様書を見てもおぼろげにしか書いてないので、こういう時にソースコードは助かる。Haxe と Happy ABC と Tamarin のコードを交互に見て、参考にしている。特に Happy ABC のインストラクション設定ファイルからコードを自動生成するやり方はかっこいいと思った。Scheme だとマクロを駆使して DSL するとかっこいいのかも知れないけど、使い方覚えるの面倒なので今の所やっていない。あと細かい話だけど気をつけている点は、変数名などを仕様書と同じにする事。特に Haxe の名前ルールが全然違って検索に苦労した経験から、名前は変えないでおこうと決めた。scheme で普通シンボルの区切りが - なのが所々 _ になってしまって変だけど、気にしないでやっている。

そんな感じです。