yarv-dev:296
From: MAEDA Atusi <maeda-yarv atusi.org>
Date: Wed, 3 Nov 2004 11:58:11 +0900
Subject: [yarv-dev:296] Re: multivple values (Re: multiple assgin return value)
Yukihiro Matsumoto <matz ruby-lang.org> writes: > |もともと、 > | a, b = [1, 2] > |でも > | a, b = *[1, 2] > |でも同じ、なのがちょっと良く分からないんですが。 > > いや、これは直します。 ああ、そうか。 def m return 1, 2 end a, b = m() でaに1が、bに2が入るようにしたいのは同じだけど、現状ではそれが配列経由 になっているってことですか。 で、ささださんの提案は、 ・多値returnなんて入れないで、配列を返すだけにする。 ・多重代入の右辺は 「式1, 式2, ...」 または 「* 配列になる式」だけ許す。 ね。 一人前の(first-classな)「多値」というものをあきらめるならば、これも、 現在のRubyの仕様も、どちらもそれなりに妥当な仕様だとは思います。「多値 めいたもの」が表れるのは多重代入の右辺だけなら、そこだけの特別な仕様を どうしようとあまり問題にはならない。 ------ 多値を(配列に依存せず)first classなものとして扱えるようにするためには、 配列を経由することなく、 ・多値を生成できる(たとえば、メソッドから返せる) ・多値を変数に代入できる(変数に束縛できる) ・多値を引数としてメソッドに渡せる ができれば良さそうに思うのですけど、たとえばCommon Lispだと、 多値の生成: (values 値1 値2 ...) (リストから多値の生成: (values-list リスト) ) 多値の代入: (multiple-value-setq (変数1 変数2 ...) 多値式) 多値の束縛: (multiple-value-let (変数1 変数2 ...) 多値式 式 ...) 多値を引数とする呼び出し: (multiple-value-call 関数 多値式1 多値式2 ...) というようになってます。実装では、多値の生成と、その他の部分(多値を受 けとる文脈/continuation/consumer)の両者のプロトコルが重要になります。 現在のRubyだと、 多値の生成: 式1, 式2, ... は多重代入の右辺だけ? (配列から多値の生成: *配列 ) 多値の代入: 変数1, 変数2, ... = 多値式 多値を引数とする呼び出し: まだない??? なのかな? first classな多値でなく、配列を中心に考えると、 メソッドから配列を返す: return 式1, 式2, ... 配列を生成する: [式1, 式2, ...] 代入: 変数1, 変数2, ... = *配列 呼び出し: メソッド(..., *配列, ...) となって、これはこれで完結していますよね。 一つの案として、上で欠けてるように思う、 ・配列とは関係なく多値を生成する一般的な方法 ・配列とは関係なく、多値を引数としてメソッドを呼び出す方法 がはっきり決まれば良いのかな、と思いました。あと、 ・多値が、いろいろなcontextに表れた時の扱い もクリーンアップする必要があると思います。条件式に多値が返ってきたらど うなるとか。andやorやif ... endやcase ... endは多値を返すのかどうか、 とか。(Common Lispでは、and, orは最後の引数以外 多値を返しません。) 以下、とりとめなく書きますが… ・配列とは関係なく多値を生成する方法 + return 式1, 式2, ... だけ、で良いのかな。 + 「式の数=返す値の数」は成り立つだろうか? return meth() で、「meth()」が多値を生成する時はどうなる? + メソッドの最後の式(暗黙のreturn)がmeth()の時は? + 上は、return が「多値を生成する」役割と「他の式の値を受けとる context」の役割を兼ねてしまうからややこしいのではないだろうか。 + 多重代入の右辺の「式1, 式2, ...」は多値の生成と解釈するのかな。 + returnとか多重代入の右辺に限らず「多値を生成する式の文法」があると よいのだろうか。 + 「returnや多重代入に限らず、どこでも式1, 式2, ... が多値の生成法だ」 としちゃうと混乱しそう。 + values(式1, ...) とか? でも a, b = values(1, 2) はちょっと… + *[式1, 式2, ...]とか? + Common Lispでいうpsetq (psetf)と、multiple-value-setqを同一視しちゃ うのが本当に良いのかどうか。 ・配列とは関係なく、多値を引数としてメソッドを呼び出す方法 + mv_call(obj, method, 多値式1, ...) …は醜いか。 + かといって obj.method(..., * 多値式, ...) だと、 obj.method(..., * m(), ...) で、m()が1つの配列を返した時と多値を返 した時をどう区別するか。 もっと思い切った案として、 ・(式1, 式2, ...)という記法は、いかなる場合も多値を表す。 優先度が許すなら、括弧は適宜つけたり外したりできる。 (式1, (式2, 式3), 式4)は(式1, 式2, 式3, 式4)と同じ。 ・メソッドは、多値を受けとる。 obj.method 多値式 とか。すべてのメソッド呼び出しがmv_callになっちゃうと混乱するかな。実 引数の数が、メソッド呼び出しのコードを見ても分からない。 あるいは、 ・(式1, 式2, ...)という記法は、[式1, 式2, ...]と同じく配列を表す。 ・全てのメソッドは、配列を1つ受けとり、配列を1つ返す。 とか。これは無茶か。 非常に消極的な案 ・多重代入は多値とは関係ない、単なる文法(psetq)である。 ・メソッドから多値は返せない。 これに配列の特別扱いを加えれば、ほぼ現状と同じになっちゃうか。 余談ですが、MLやHaskellに多値がない新たな理由に思い至りました。 これらの言語では、そもそも多引数の関数というものがないので、 「すべての関数は1つの引数を受けとり1つの値を返す」で十分きれいに できているのですね。 前田敦司 -- ML: yarv-dev quickml.atdot.net 使い方: http://www.atdot.net/~ko1/quickml
268 2004-11-01 19:28 [ko1 atdot.net ] multiple assgin return value 269 2004-11-01 19:56 ┗[matz ruby-lang.org ] 270 2004-11-02 05:27 ┗[ko1 atdot.net ] 271 2004-11-02 05:38 ┣[ko1 atdot.net ] 273 2004-11-02 08:01 ┃┗[matz ruby-lang.org ] 272 2004-11-02 08:00 ┣[matz ruby-lang.org ] 274 2004-11-02 08:15 ┃┗[ko1 atdot.net ] 275 2004-11-02 08:25 ┃ ┗[matz ruby-lang.org ] 276 2004-11-02 09:14 ┃ ┗[ko1 atdot.net ] 277 2004-11-02 09:36 ┃ ┗[matz ruby-lang.org ] 279 2004-11-02 14:05 ┃ ┣[maeda-yarv atusi.org] multivple values (Re: multiple assgin return value) 280 2004-11-02 14:49 ┃ ┃┗[matz ruby-lang.org ] 281 2004-11-02 17:54 ┃ ┃ ┣[maeda-yarv atusi.org] 282 2004-11-02 18:14 ┃ ┃ ┃┗[ko1 atdot.net ] 284 2004-11-02 19:37 ┃ ┃ ┃ ┗[maeda-yarv atusi.org] 283 2004-11-02 18:16 ┃ ┃ ┗[ko1 atdot.net ] 285 2004-11-02 19:47 ┃ ┃ ┣[matz ruby-lang.org ] 288 2004-11-02 20:43 ┃ ┃ ┃┗[ko1 atdot.net ] 289 2004-11-02 23:31 ┃ ┃ ┃ ┣[shugo ruby-lang.org ] 293 2004-11-03 08:35 ┃ ┃ ┃ ┃┗[ko1 atdot.net ] 290 2004-11-03 01:17 ┃ ┃ ┃ ┗[matz ruby-lang.org ] 291 2004-11-03 03:54 ┃ ┃ ┃ ┣[maeda-yarv atusi.org] 294 2004-11-03 08:57 ┃ ┃ ┃ ┃┗[matz ruby-lang.org ] -> 296 2004-11-03 11:58 ┃ ┃ ┃ ┃ ┗[maeda-yarv atusi.org] 298 2004-11-03 14:34 ┃ ┃ ┃ ┃ ┣[akr m17n.org ] 299 2004-11-03 15:39 ┃ ┃ ┃ ┃ ┃┗[maeda-yarv atusi.org] 315 2004-11-04 11:46 ┃ ┃ ┃ ┃ ┃ ┗[akr m17n.org ] 307 2004-11-04 01:49 ┃ ┃ ┃ ┃ ┗[matz ruby-lang.org ] 308 2004-11-04 02:08 ┃ ┃ ┃ ┃ ┗[shugo ruby-lang.org ] 310 2004-11-04 02:48 ┃ ┃ ┃ ┃ ┗[matz ruby-lang.org ] 292 2004-11-03 08:32 ┃ ┃ ┃ ┣[ko1 atdot.net ] 300 2004-11-03 17:36 ┃ ┃ ┃ ┃┣[matz ruby-lang.org ] 301 2004-11-03 22:19 ┃ ┃ ┃ ┃┃┗[ko1 atdot.net ] 304 2004-11-03 23:29 ┃ ┃ ┃ ┃┗[shugo ruby-lang.org ] 311 2004-11-04 02:56 ┃ ┃ ┃ ┃ ┗[ko1 atdot.net ] 312 2004-11-04 09:40 ┃ ┃ ┃ ┃ ┗[shugo ruby-lang.org ] 313 2004-11-04 09:45 ┃ ┃ ┃ ┃ ┗[ko1 atdot.net ] 314 2004-11-04 10:58 ┃ ┃ ┃ ┃ ┗[shugo ruby-lang.org ] 316 2004-11-04 12:48 ┃ ┃ ┃ ┃ ┗[ko1 atdot.net ] 295 2004-11-03 09:29 ┃ ┃ ┃ ┗[ko1 atdot.net ] 286 2004-11-02 20:05 ┃ ┃ ┗[maeda-yarv atusi.org] 287 2004-11-02 20:13 ┃ ┃ ┗[matz ruby-lang.org ] 302 2004-11-03 22:21 ┃ ┗[ko1 atdot.net ] 303 2004-11-03 22:54 ┃ ┗[matz ruby-lang.org ] 305 2004-11-03 23:31 ┃ ┗[ko1 atdot.net ] 306 2004-11-04 00:49 ┃ ┗[matz ruby-lang.org ] 278 2004-11-02 12:40 ┗[maeda-yarv atusi.org]