Edited at

SICP読書録 #12 1.3.2 lambdaを使って手続きを構築する

More than 1 year has passed since last update.

hiroshi-manabe様の日本語訳を使わせてもらいます。

練習問題等はGaucheで実行。

前回はこちら


1.3.2 lambdaを使って手続きを構築する

lambdaによって無名の手続きを作ることができる。

これで、以下の手続きを作り直してみよう。


_.scm

(define (pi-sum a b)

(define (pi-term x)
(/ 1.0 (* x (+ x 2))))
(define (pi-next x)
(+ x 4))
(sum pi-term a pi-next b))

(define (integral f a b dx)
(define (add-dx x)
(+ x dx))
(* (sum f (+ a (/ dx 2.0)) add-dx b) dx))


pi-term, pi-next, add-dx は内部でのみ利用される手続きだ。いちいちdefineで名前を付ける必要はない。


_.scm

(define (pi-sum a b)

(sum (lambda (x) (/ 1.0 (* x (+ x 2))))
a
(lambda (x) (+ x 4))
b))

(define (integral f a b dx)
(* (sum f
(+ a (/ dx 2.0))
(lambda (x) (+ x dx))
b)
dx))



letを使って局所変数を作る

次の式を計算したい。

f(x,y)=x(x+xy)^2+y(1-y)+(1+xy)(1-y)

これを、以下のように表現しよう。

\begin{align}

a&=1+xy \\
b&=1-y \\
f(x,y)&=xa^2+yb+ab
\end{align}

letを使うと、局所変数を定義できる。これで、以下のように定義できる。


_.scm

(define (f x y)

(let ((a (+ 1 (* x y)))
(b (- 1 y)))
(+ (* x (square a))
(* y b)
(* a b))))


練習問題 1.34

次の手続きを定義する。


_.scm

(define (f g) (g 2))


実行してみよう。


_.scm

gosh> (f square)

4 ; (square 2)
gosh> (f (lambda (z) (* z (+ z 1))))
6 ; ((lambda (z) (* z (+ z 1))) 2)

ここで、(f f)という手続きを実行したらどうなるか?

展開してみよう。


_.scm

(f f)

> ((lambda (f g) (g 2) f)
> (f 2)
> ((lambda (f g) (g 2) 2)
> (2 2)

というわけで、以下のような結果となる。


_.scm

gosh> (f f)

*** ERROR: invalid application: (2 2)