Scheme:多値で出た議論
セマンティックスとか継続との絡みは良く分かってないのですが、 対称性という意味でいうと、
(func0 (func1 arg1) (func2 arg2) (func3 arg3) ...) => (func0 val1 val2 val3 ...)
という風に複数の式からの返り値を引数にとる。 これが n-in だとすると
(???? func1 func2 func3 ... (values val1 val2 val3 ...))
=> どういう動作になるかは分からないけど UNIX の fork みたいな感じで
(func1 val1) (func2 val2) (func3 val3) ....
というスレッドの分岐みたいのが起こるのが m-out な気がしちゃうなぁ。
(apply func arg1 arg2 ...)
という n-in に対して
(apply-val-to-funcs values func1 func2 func3 ...)
で、 values が多値を返す式、 とすると apply-val-to-funcs は call-with-values に相当するやつみたいなイメージなんだけど、個人的には。 values の返す複数の値が順に func1 func2 ... にばらまかれるような感じ。 cut-sea:2004/06/03 14:32:51 PDT
teranishiさんによる実装例
(define-syntax call-each-values (syntax-rules () ((_ (func funcs ...) args ...) (call-each-values "gensym" () () (args ...) (funcs ...) (func funcs ...) (args ...))) ((_ "gensym" l (lr ...) () () (func ...) (args ...)) (call-each-values "bind" (l lr ...) (l lr ...) (func ...) (args ...))) ((_ "gensym" l (lr ...) () (f g ...) (func ...) (args ...)) (call-each-values "gensym" () (l lr ...) (args ...) (g ...) (func ...) (args ...))) ((_ "gensym" (tr ...) (lr ...) (a b ...) (f ...) (func ...) (args ...)) (call-each-values "gensym" (t tr ...) (lr ...) (b ...) (f ...) (func ...) (args ...))) ((_ "bind" (() ...) ((l ...) ...) (func ...) ()) (values (func l ...) ...)) ((_ "bind" ((v vr ...) ...) ((l ...) ...) (func ...) (arg args ...)) (receive (v ...) arg (call-each-values "bind" ((vr ...) ...) ((l ...) ...) (func ...) (args ...))))))
使用例
(define (qr-list a b) (if (or (null? a) (null? b)) (values () ()) (call-each-values (cons cons) (quotient&remainder (car a) (car b)) (qr-list (cdr a) (cdr b))))) gosh> (qr-list '(10 9 8 7 6) '(5 4 3 2 1)) (2 2 2 3 6) (0 1 2 1 0)
見てくれが通常の再帰に近くなるし、一時変数を使う必要もありません。
Tag: 多値