test/dynwind.scm (3)

昨晩、自宅対応なお仕事 (しかも緊急) な割り込みを受けつつへろへろながら投入したエントリにて以下の試験がよく分からん、と書きました。

;; continuation with multiple values

(test* "call/cc (values)" '(1 2 3)
       (receive x (call-with-current-continuation
                   (lambda (c) (c 1 2 3)))
         x))

これ、call/cc に渡す手続きオブジェクトの引数に何が渡されるか、がイメージできてれば、さほど難しい話ではない事に本日帰宅後、気がつきました。
例えば

(* 2 (fact 10))

の (fact 10) の続きの計算は (lambda (a) (* 2 a)) である、と以前のエントリにて書いてます。てーコトは

(* 2 (call/cc (lambda (cont) (cont (identity 2)))))

の cont には (lambda (a) (* 2 a)) がナニ。
と、いう事は

(receive x (call/cc (lambda (c) (c 1 2 3))) x)

の c にはどんな手続きがセットされるのか。

むむ

ええと、上記の例を call/cp で書けば良い?

(call/cp (lambda (a) (receive x a x))
	 (lambda (cont) (cont 1 2 3)))

で、考えてみるに、receive の第二引数は_多値を返す式_にならざるを得ない?
展開してみたら以下。

((lambda (cont) (cont 1 2 3)) (lambda (a) (receive x a x)))

さらに展開

((lambda (a) (receive a x)) 1 2 3)

これ、引数の数が合わない。困った時には継続を取り出してみる。って昨晩もしたな。

gosh> (define cont #f)
cont
gosh> (receive x (call/cc (lambda (c) (set! cont c) (c 1 2 3))) x)
(1 2 3)
gosh> cont
#<subr continuation>
gosh> (cont 1 2)
(1 2)
gosh> 

を、リストになっとるな。values ではないんですが ...
って REPL に戻るまで続くからリストになるのか。むははは。

次もハードル高い

これは ...

;; continuation invoked while inline procedure is prepared.
;; a test to see call/cc won't mess up the VM stack.

(define (callcc-test2)
  (let ((cc #f)
        (r '()))
    (let ((s (list 1 2 3 4 (call/cc (lambda (c) (set! cc c) 5)) 6 7 8)))
      (if (null? r)
          (begin (set! r s) (cc -1))
          (list r s)))))
    
(test "call/cc (inline)" '((1 2 3 4 5 6 7 8) (1 2 3 4 -1 6 7 8))
      callcc-test2)

えーと、これって継続 (の入口?) は

(lambda (a) (list 1 2 3 4 a 6 7 8))

ってコト?
# なんか違うな。コメントの記述は一体何だろ。