[前][次][番号順一覧][スレッド一覧][生データ]

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]