BiwaScheme の継続の挙動を観察している記事を見掛けた。
- mapのcallbackの中で作られる継続のextentが (多分) mapに戻るまでで,次のコードがうまく動かない:
(define cont (car (map (lambda (x) (call/cc (lambda (c) c))) '(1)))) (cont 3) cont ; => #<Closure> ; Gaucheだと => 3http://d.hatena.ne.jp/gengar/20101013/1286904238
R6RS 的には同じ変数に対して再度 define は出来ないので、継続を起動して cont に 3 を define しようとすればエラーになるのが正しい挙動じゃないかと最初は思った。
が、この場合は全体が letrec* であるかのように扱われるはずなので、それを踏まえて考えてみることにした。 R6RS の「Appendix B. Sample definitions for derived forms」の項目に letrec* の定義例がある。
(define-syntax letrec* (syntax-rules () ((letrec* ((var1 init1) ...) body1 body2 ...) (let ((var1 <undefined>) ...) (set! var1 init1) ... (let () body1 body2 ...)))))
この定義例をあてはめると (cont 3) とした場合、 (set! cont 3) からの継続が起動されるはず。 当初私が思っていたのとは違って、単に set! すると考えられる。 (set! cont 3) の後に (cont 3) が評価され、それはつまり (3 3) なのであるから 3 は手続きではない旨のエラーが通知されるというのが R6RS 的には正しい挙動だと思う。 R5RS だとたぶん未定義。
と、いう解釈でいいかなぁ。
追記
letrec* について注記があることを教えてもらった。
@SaitoAtsushi define の右辺の継続は複数回起動してはいけないと書いてあったような記憶があったので letrec* とは異なる場合があるのかと思ったのですが、 letrec* の束縛部の右辺の継続についても似たような注記がありますね
2010-10-13 20:13:36 via web to @SaitoAtsushi
It must be possible to evaluate each
http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_idx_408without assigning or referring to the value of the corresponding or the of any of the bindings that follow it in . Another restriction is that the continuation of each should not be invoked more than once.
Implementation responsibilities: Implementations must, during the evaluation of anexpression, detect references to the value of the corresponding or the of any of the bindings that follow it in . If an implementation detects such a violation of the restriction, it must raise an exception with condition type &assertion. Implementations may or may not detect that the continuation of each is invoked more than once. However, if the implementation detects this, it must raise an exception with condition type &assertion.
これによるとやっぱり init のところの継続を再度起動するのはよろしくないらしい。 起動されたのを処理系は検出しなくてもよいともあるわけだけど、検出せずに通過した場合にはどうなるべきなんだろう?
Document ID: 397ea92fe8fe03f219104cefe87ed312