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))))) >