2011/04/06

多値と receive

多値は便利ですよね。多値がサポートされてると嬉しいですね。無くても困らないかもしれませんけどね。common lisp の multiple-value-bind destructuring-bind みたいな分配束縛があれば多値は無くても良いような気もするんですがどうなんでしょうか。match-let で良いじゃんという話もありますか。
世の中には「多値」の他に「多価」というのもあるらしいですね。よく知りませんが。

多値は便利なので使う機会も少なくないですが、receive(srfi-8)が多段にネストしてくるとウザいです。そうすると let に対する let* みたいな、receive に対する receive* が欲しくなるので書くわけです。
(define-syntax receive*
  (syntax-rules ()
    ((_ () . body)
     (begin . body))
    ((_ ((var val)) . body)
     (receive var
         val
       (begin . body)))
    ((_ ((var val) x ...) . body)
     (receive var
         val
       (receive* (x ...) . body)))
    ))

で、使ってみるわけです。
(define (foo)
  (values 'a 'b 'c))

(define (bar)
  (apply values '(1 2 3 4 5)))

(define (baz)
  (values + - * /))

(receive* (((a b c)(foo))
           ((v1 v2 . rest)(bar))
           (procs (baz)))
    (list a b c v1 v2 rest procs))
で、これなんて let*-values ?
と、しばらくして気づくわけです。



scheme wiki にこんなページが。
そういや、多値が継続で実装できるって話が今でもよくわからないです。

追記

教えて頂きました。
@valvallow 多値は継続手続きを多引数に拡張したものと思えばわかりやすいかも。call/ccで取り出せる継続が一引数の場合でも http://scheme.com/tspl4/control.html#./control:h8 みたいにすれば多値をエミュレートできます
でもやっぱりわかりませんorz

プログラミングGauche

0 件のコメント:

コメントを投稿