inline展開再び - Scheme VM
手続きの inline 展開に再び挑む。
begin問題
inline 展開は1つのS式を受け取り、1つ以上のS式を返す。そのことから inline 展開される文脈次第では begin で囲まなければいけない。
(define (func x y) (x) (y)) (if (func a b) c d) => (if (begin (a) (b)) c d)
こういうの。
副作用問題
引数に手続きを渡された場合、そのまま展開するとまずい場合がある。
(define (hoge a) (+ a a)) (hoge (read)) => (+ (read) (read)) ;; これはまずい
引数にシンボルや数値以外が来たらとりあえず let1 をはさんでやる。
(let1 G1 (read) (+ G1 G1))
A-reduction がうまく言っていれば、手続きの引数の位置には変数しかこないのでこれは必要ないかもしれないが自信無し。
気をつけること
ちょっと実装に手こずったので反省材料を探し改善案を。
- 簡単にテストできる環境を用意する
- 手続きの引数と戻り値を特性を把握する
- 難しいときは図と自然言語で表現してみる
- (require 'trace) を使う
あたりかな。