SICP 再読 1

図形言語を実装したのはいいものの、基本を全然分かってないので、もう少し基本的なところからやり直すことにする。

最初の最初からよく分かってない。

・1.3 作用的順序と正規順序
式を評価する順番らしいが、何度読んでもよく分からん。

正規順序 とりあえず一回全部展開してから、まとめて行くやり方。で、あってる?
作用的順序 Gaucheとか普通のschemeは、これらしい。置き換えていくらしい。


とりあえず、「手続き作用の置換えモデル」の考え方として、
2-6のChurch数を見る。


(define zero (lambda (f) (lambda (x) x)))

(define (add-1 n)
(lambda (f) (lambda (x) (f ((n f) x)))))

;; 上記二つの手続きから one / two / three を作る。

;; (define one (add-1 zero)
;; -> (add-1 zero)
;; -> (lambda (f) (lambda (x) (f (( zero f) x))))
;; -> (lambda (f) (lambda (x) (f (((lambda (f) (lambda (x) x)) f) x))))
;; -> (lambda (f) (lambda (x) (f (( lambda (x) x) x))))
;; -> (lambda (f) (lambda (x) (f x) ))

(define one (lambda (f) (lambda (x) (f x))))



;; (define two (add-1 one)
;; -> (add-1 one)
;; -> (lambda (f) (lambda (x) (f (( one f) x))))
;; -> (lambda (f) (lambda (x) (f (((lambda (f) (lambda (x) (f x)) f) x))))
;; -> (lambda (f) (lambda (x) (f (( lambda (x) (f x) ) f) x)))
;; -> (lambda (f) (lambda (x) (f ((f x) x)))
;; -> (lambda (f) (lambda (x) (f ( f x) ))

(define two (lambda (f) (lambda (x) (f (f x)))))
(define three (lambda (f) (lambda (x) (f (f (f x))))))

;; 加算手続き
(define (addnm n m)
(lambda (f) (lambda (x) ((n f) ((m f) x)))))

;;確認
(define (plus1 x) (+ x 1))
((zero plus1) 0) ; => 0
((one plus1) 0) ; => 1
((two plus1) 0) ; => 2

(((addnm three two) plus1) 0) ; => 5

頭がくらくらしてくる。

答えはカンニングしたけど、途中がなんか違う気がする。
どこまでが関数で、その適用で、というふうに式を見る訓練がまるで出来てない。ぽい。

データが手続きとして定義されるという考え方自体も意味不明。
なんか実用的な意味で、嬉しいことがあるんだろうか。

この辺がCにおけるポインタみたいなもんなんだろうか。
この辺が自由に理解できれば、少しは楽になるんだろうか。


あと、関係ないけど
letは、lambdaの糖衣構文っていまさらながら理解。

 (let ((x 0)) 
   (+ x 1))
;; は、
 ((lambda (x) (+ x 1)) 0)
;; と等価なのか。なるほど。

スーパーpre記法の使い方も理解した。ありがとう!コメントくれた人。