高校数学の窓過去問検索

Scheme入門 第11章 黒じゃあー!


さて前回は、関数を渡す関数というものが作れることを説明しました。今回は、関数を返す関数も作ってみましょう。もちろん無名関数を作る lambda を使ってね。




(define (f) (lambda (x) (+ x 1)))




この関数 f(lambda (x) (+ x 1)) を返すはずです。(lambda (x) (+ x 1)) は値を1だけ増やす関数(相変わらず芸が無いというか…)ですから、f は値を1だけ増やす関数を返すはずです。試してみましょうか。




(display ((f) 4))




(f) は関数を返しますから、((f) 4) でその関数を呼び出せるはずです。






結果は期待通り 5 が表示されます。では次の例もご覧下さいませ。




(define (f y) (lambda (x) (+ x y)))




xy を足す関数を返す関数 fy って、無名関数じゃなくて f の引数ですけど、大丈夫なんでしょうか。




(define (f y) (lambda (x) (+ x y)))
(display ((f 4) 5))







9 と表示されます。どうやら大丈夫なようです。じゃあ、関数を変数に保存しておいて、後で使ってみるとか。




(define (f y) (lambda (x) (+ x y)))
(define inc4 (f 4))
(display (inc4 5))







結果はやはり 9。全然平気です。f の中で作られた関数は、f に渡した y の値を覚えているようです。この仕組みをクロージャと呼びます。関数は、そのプログラムの中身の他に、関連する変数も持っているのです。
この変数は、作られた関数が消滅するまで存在していることになります。




クロージャの性質を示す良い例として、カウンターを紹介しましょう。関数 make-counter に初期値を与えると、関数を返します。この関数は、呼び出すたびに値が1ずつ増えていくのです。




(define (make-counter x)
(lambda ()
(set! x (+ x 1))
x))

(define counter (make-counter 0))

(display (counter))

(newline)
(display (counter))

(newline)
(display (counter))

(newline)




counter を呼び出すたびに1ずつ増えていくと思います。






make-counter が呼ばれたときの xcounter が覚えていて、呼び出すごとに set! で値を更新していくためです。なかなか奇妙なものですね。クロージャを利用すると色々と面白いことが出来ますが、それはまたの機会に。




第11章・完




第12章へ












DrScheme






  1. DrScheme での Language Pack の選択

  2. Scheme の単純な式「(+ 3 2)」, 「(- 10 4)」

  3. Scheme の単純な式(括弧の入れ子)

  4. Scheme の単純な式 (DrScheme の定義ウインドウ)

  5. 関数 area-of-disk の定義と,関数適用

  6. 関数 area-of-disk,変数 PI の定義と,関数適用(1)

  7. 関数 area-of-disk,変数 PI の定義と,関数適用(2)


0 コメント: