R5RSを初めて読んだ。 call/cc
が少しわからなくなった。 ---
多値を返すための values
を call/cc
で定義してて、なんで多値になるのか分からない。
(define (values . things)
(call/cc (lambda (cc) (apply cc things))) )
とあって、ためしに実験
gosh> (define (balues . things) (call/cc (lambda (cont) (apply cont things))))
balues
gosh> (balues 1 2 3)
1
2
3
gosh> (receive (a b c) (balues 1 2 3) (list c b a))
(3 2 1)
できてる。なんで出来るのか分からない。 values手続きの定義本体のccは、大域脱出をするただのid関数だと思うんだけど。 じゃあ、もうそれでいいのかな。
dynamic-wind
で出てくるサンプルコードも果てしなく難しい。 意義は分かった。そのthunkがどのタイミングででも呼び出される前後には beforeとafterが呼び出される。それはいいんだけど
(define path '())
(define c #f)
(define (add s) (push! path s))
(dynamic-wind
(lambda () (add 'connect))
(lambda ()
(add (call/cc (lambda (c0) (set! c c0) 'talk1))))
(lambda () (add 'disconnect)) )
(c 'talk2)
これを読み込ませてREPLで実験
gosh> path
(disconnect talk2 connect disconnect talk1 connect)
gosh> c
#<subr continuation>
gosh> (c 'talk-final)
シェルが値を返しました 70
なんか、エラーなのかよく分からないエラーが出る。
以上。
choose マクロは
http://www.shido.info/lisp/scheme_amb.html
による。(ちょっと違う)
問題は
http://www.geocities.jp/m_hiroi/light/abcruby17.html
にあった.
出典:Leon Sterling, Ehud Shapiro (著), 松田利夫 (訳), 『Prolog の技芸』, 共立出版, 1988, (278頁より)
の、もの。
(define (fail) '@)
(define-syntax choose
(syntax-rules ()
((_) (fail))
((_ a) a)
((_ a b ...) (let ((fail0 fail))
(call/cc (lambda (cc)
(set! fail (lambda () (set! fail fail0) (cc (choose b ...))))
(cc a))))) ))
;;;
(let ((Michael (list (choose 1 2 3) 'bascket (choose 'Islam 'Australia 'America)))
(Simon (list (choose 1 2 3) (choose 'bascket 'tennis 'clicket) 'Islam))
(Richard (list (choose 1 2 3) (choose 'bascket 'tennis 'clicket) (choose 'Islam 'Australia 'America))) )
(define (require cond)
(if (not cond) (fail)))
(define (unique? ls)
(if (< (length ls) 2) #t
(if (member (car ls) (cdr ls)) #f
(unique? (cdr ls)))))
(require (unique?
(map car (list Michael Simon Richard))))
(require (unique?
(map cadr (list Michael Simon Richard))))
(require (unique?
(map caddr (list Michael Simon Richard))))
(require (< (car Michael)
(car (find (lambda (p) (eq? (caddr p) 'America))
(list Michael Simon Richard)) )))
(require (< (car Simon)
(car (find (lambda (p) (eq? (cadr p) 'tennis))
(list Michael Simon Richard)))))
(require (= 1 (car (find (lambda (p) (eq? (cadr p) 'clicket))
(list Michael Simon Richard)))))
(display #`"Michael : ,Michael\n")
(display #`"Simon : ,Simon\n")
(display #`"Richard : ,Richard\n")
'done)
; Michael : (2 bascket Australia)
; Simon : (1 clicket Islam)
; Richard : (3 tennis America)