🔙 Back to Top

Sun Jul 14 20:27:00 JST 2013

Scheme, 現在継続と名前付き let の関連?

疑問点

あたかも継続を返すように名前付きletは返せないのか なんでエラーが出ず下のコードは動いてしまうのか

(define (hoge)
  (let loop ((i 0))
    (if (odd? i) (values i (delay (loop (+ i 1)))) (loop (+ i 1)))))

hogeは自然数を見ていって、奇数とその次の奇数を探す「継続もどき」の多値を返す

gosh> (hoge)
1
#<promise 0x8786910>

2つ目を実行してみよう

gosh> (receive (j next) (hoge) (force next))
3

あれ? ここは多値が帰ってきて欲しいのだけれど????

追記 (Tue Aug 6 10:53:06 JST 2013)

名前付きletの名前を返すことは,確かに再帰手続きを返すことに等しい

gosh> (let rec ((x -1))
  (cond [(< x 0) rec]
        [(zero? x) 1]
        [exe (* x (rec (- x 1)))]))
#<closure rec>

ここで,(< x 0) というのはrecを返すためだけのもの

gosh> (define f (let rec ((ls -1)) (cond [(< ls 0) rec] [(zero? ls) 1] [else (* ls (rec (- ls 1)))])))
f
gosh> (f 10)
3628800

最初のやつの問題は,単にこういうこと

gosh> (values 1 2)
1
2
gosh> (force (delay (values 1 2)))
1

valuesじゃなくてやっぱりちゃんとcons使うべき

gosh> (let rec ((ls '(9 8 7 6 5))) (if (null? ls) #f (cons (car ls) (delay (rec (cdr ls))))))
(9 . #<promise 0x9d5f590>)
gosh> (let rec ((ls '(9 8 7 6 5))) (if (null? ls) #f (begin (set! cc (delay (rec (cdr ls)))) (car ls))))
9
gosh> (force cc)
8
gosh> (force cc)
7

はい,call/ccとか必要ない