Schemeの評価順序
Schemeは括弧の中を先に計算するのかと思っていたが、どうやら違う。Schemeの評価順序を調べてみた。
実験
まずはC言語で。
int i = 1; printf("%d", i + ((i = 5), 2)); // 7
絶対使わなそうな書き方だけど、C言語では括弧の中が先に評価されるから、括弧の中で代入文を使うとiの値は5に変わる。i + 2をすると答えは7だ。
次にSchemeを見てみる。
(define i 1) (define (test1) (+ i (begin (set! i 5) 2))) (test1) ; 3 (test1) ; 7
1回目の評価と、2回目の評価の結果が違う。
代入の順番を変えると、
(define i 1) (define (test2) (+ (begin (set! i 5) 2) i)) (test2) ; 7
答えは常に7。
ということは・・・
(+ i (begin (set! i 5) 2))の場合、
- iに1を代入
- (+ 1 (begin (set i 5) 2))
- iの値を変更
- (+ 1 (begin 2))
- beginを評価
- (+ 1 2)
- +を評価
- 3
となっているようだ。
つまり、Schemeの評価順序は
「括弧を先に評価」ではなく、「プログラムのツリーを巡りながら評価」している。
あああああああああああああああああ
そうか!!わかった!!
スタックの内容がまるで逆
C言語はスタックに変数の内容を溜め込む。
a = 1; b = 3; c = 5;
Schemeはスタックに今まで巡ってきた評価の履歴を溜め込む。
(+ 1 (+ 2 (+ 3 (call/cc) a) b) c) |<--- 履歴 -->|
要するに全然違う内容をスタックに溜め込んでる。
スタック=変数みたいな感じなので、別の命名を考えた。これこそが継続
継続の謎が解けた!!!!!!!!!!!
しまった。継続はもうちょっと後でとか言ってた気がする。
もうちょっと・・・
(set! op +)とやると、処理系によって動作が異なるようだ。
面白いのでお試しアレ。