プログラミング再入門

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

Scheme修行 第19章 宝石泥棒(その1)

Scheme固有の継続の使用方法を習います。

ノート:

deepB

まず、deepのおさらい。

> (deep 6)
((((((pizza))))))
> 
deepB

再帰の果てにmが0になった時点でletcc (call-with-current-continuation)して続きの関数を大域変数のtoppingsに設定している事以外は普通のdeepと同じ。

> (deepB 6)
((((((pizza))))))
> 

「jumpを適用する」とは「letccのから返る」事を意味している。jumpへの引数はそのままletccの関数値である。従ってjumpを適用する事でdeepBの処理の途中から再開出来る事を意味する。しかも何回でも再開出来る。

> (toppings (quote mozzarella))
((((((mozzarella))))))
> (toppings (quote basil))
((((((basil))))))
> (let ((e 'cake))
    (toppings e))
((((((cake))))))
> (toppings (quote pizza))
((((((pizza))))))
> 

toppingsを介してjumpを適用する事は単に関数を適用する事とは全く状況が異なる。

> (let ((m 'cake))
    (cons (toppings m) (quote ())))
((((((cake))))))
> (cons
   (cons
    (cons (toppings (quote mozzarella))
          (quote ()))
    (quote ()))
   (quote ()))
((((((mozzarella))))))
> 

何かの処理の途中でtoppingsあるいはjumpが適用された場合、それまでの状況(上記ではconsの引数を処理している最中であるとか、戻って来たら(quote ())とconsするとか言った状況)は全て捨て去られletccが呼ばれた時点の状況に置き換わる。

> (deepB 4)
((((pizza))))
> (cons (toppings (quote cake))
        (toppings (quote cake)))
((((cake))))
> (cons (toppings (quote cake))
        (cons (toppings (quote mozzarella))
              (cons (toppings (quote pizza))
                    (quote ()))))
((((cake))))
> 

脚注にある様に引数の評価順序は規定されていないとの事だが、DrRacketでは最初の(toppings (quote cake))が最初に評価されてそこで実行は終わった。

deep&co
> (deep&co 0 (lambda (x) x))
pizza
> (deep&co 6 (lambda (x) x))
((((((pizza))))))
> (deep&co 2 (lambda (x) x))
((pizza))
> 

mが0の場合は、いきなり(lambda (x) x)が適用されて終わり。

mが2の場合は、

m k x
2 (lambda (x) x) ( (pizza) )
1 (lambda (x) (k (cons x (quote ())))) (pizza)
0 (lambda (x) (k (cons x (quote ())))) pizza
deep&coB

上記の表の一番したのkを大域変数から参照させておくとletccで行った事とほぼ同じ事が出来る。
ある段のlambdaに含まれているkは前の段の環境を含んだクロージャなので、最初に呼び出した時の(lambda (x) x)から全てのクロージャが数珠繋ぎで残っている。これを呼び出す事でletccを使ってそこの状況を保存するのと同じ効果が得られる。

> (deep&coB 2 (lambda (x) x))
((pizza))
> (toppings (quote mozzarella))
((mozzarella))
> (toppings (quote cake))
((cake))
> 

しかも、ここでのtoppingsは普通の関数として呼べる。

> (deep&coB 4 (lambda (x) x))
((((pizza))))
> (cons (toppings (quote cake)) (toppings (quote cake)))
(((((cake)))) (((cake))))
> (cons (toppings (quote cake))
        (cons (toppings (quote mozzarella))
              (cons (toppings (quote pizza))
                    (quote ()))))
(((((cake)))) ((((mozzarella)))) ((((pizza)))))
>