プログラミング再入門

プログラミングをもう一度ちゃんと勉強する読書ノート

Scheme修行 第16章 位置について、セット、バン!(その1)

set!を使ったテクニックの続きです。

ノート:

sweet-tooth

内容的に目新しい事は無いが、やり取りを実際に確かめてみる。

> (define sweet-tooth
    (lambda (food)
      (cons food
            (cons (quote cake)
                  (quote ())))))
> (define last (quote angelfood))
> (let ((x 'chocolate))
    (sweet-tooth x))
(chocolate cake)
> last
angelfood
> (let ((x 'fruit))
    (sweet-tooth x))
(fruit cake)
> last
angelfood
> (define sweet-toothL
    (lambda (food)
      (set! last food)
      (cons food
            (cons (quote cake)
                  (quote ())))))
> (sweet-toothL (quote cocolate))
(cocolate cake)
> last
cocolate
> (sweet-toothL (quote fruit))
(fruit cake)
> last
fruit
> (let ((x 'cheese))
    (sweet-toothL x))
(cheese cake)
> (sweet-toothL (quote carrot))
(carrot cake)
> (define ingredients (quote ()))
> (define sweet-toothR
    (lambda (food)
      (set! ingredients
            (cons food ingredients))
      (cons food
            (cons (quote cake)
                  (quote ())))))
> (let ((x 'chocolate))
    (sweet-toothR x))
(chocolate cake)
> ingredients
(chocolate)
> (sweet-toothR (quote fruit))
(fruit cake)
> ingredients
(fruit chocolate)
> (let ((x 'cheese))
    (sweet-toothR x))
(cheese cake)
> ingredients
(cheese fruit chocolate)
> (sweet-toothR (quote carrot))
(carrot cake)
> ingredients
(carrot cheese fruit chocolate)
> 

sweet-toothRは過去の引数をリストingredientsに蓄える。

deep

deepの定義を動作確認。

> (deep 3)
(((pizza)))
> (deep 7)
(((((((pizza)))))))
> 

deepRの定義を動作確認。

> (deepR 3)
(((pizza)))
> Ns
(3)
> Rs
((((pizza))))
> (deepR 5)
(((((pizza)))))
> Ns
(5 3)
> Rs
((((((pizza))))) (((pizza))))
> (deepR 3)
(((pizza)))
> Ns
(3 5 3)
> Rs
((((pizza))) (((((pizza))))) (((pizza))))
> 

findの動作確認。同じ状況にする為に再び(deepR 3)、(deepR 5)、(deepR 3)を実行。

> (deepR 3)
(((pizza)))
> (deepR 5)
(((((pizza)))))
> (deepR 3)
(((pizza)))
> Ns
(3 5 3)
> Rs
((((pizza))) (((((pizza))))) (((pizza))))
> (find 3 Ns Rs)
(((pizza)))
> (find 5 Ns Rs)
(((((pizza)))))
> (find 7 Ns Rs)
. . mcar: expects argument of type <mutable-pair>; given ()
> 

deepMの定義を動作確認する。

> Ns
(3 5 3)
> Rs
((((pizza))) (((((pizza))))) (((pizza))))
> (set! Ns (cdr Ns))
> (set! Rs (cdr Rs))
> Ns
(5 3)
> Rs
((((((pizza))))) (((pizza))))
> (deepM 3)
(((pizza)))
> Ns
(5 3)
> Rs
((((((pizza))))) (((pizza))))
> (deepM 6)
((((((pizza))))))
> Ns
(6 5 3)
> Rs
(((((((pizza)))))) (((((pizza))))) (((pizza))))
> 

deepからdeepMを再帰適用する様にして動作を確認する。

> Ns
()
> Rs
()
> (deepM 9)
(((((((((pizza)))))))))
> Ns
(9 8 7 6 5 4 3 2 1 0)
> Rs
((((((((((pizza)))))))))
 ((((((((pizza))))))))
 (((((((pizza)))))))
 ((((((pizza))))))
 (((((pizza)))))
 ((((pizza))))
 (((pizza)))
 ((pizza))
 (pizza)
 pizza)
> 

最後にNsおよびRsをグローバルな変数にせずクロージャからのみアクセス出来る変数にした定義で動作確認をする。

> (deepM 16)
((((((((((((((((pizza))))))))))))))))
> Ns
. . reference to undefined identifier: ns
> Rs
. . reference to undefined identifier: rs
> 

この見えない、Ns、Rsの内容を確認する手段はあるのだろうか?

新しいfindの仕様下で動作確認をする。

> (deepM 16)
((((((((((((((((pizza))))))))))))))))
> (deepM 0)
pizza
>