Hi liszt,

I read on Matz' Ruby2.0 slides that the semantics
of Multiple Values will change.  Are these already
decided?  Here are my ideas about the subject.
I want to post it as a RCR, but I would like to have 
your opinion, or criticism first.  Also I am not 
very familiar with the RCR mechanism.
It is already gotten to a quite large and complicated document.

Thanks,
Kristof

TITLE
Semantics of Multiple Values

ABSTRACT
This RCR describes a possible change in semantics of multiple
values, by making them equivalent to argument passing.

PROBLEM
Currently Array's are used as multiple variables, which
creates some ambiguous or unclear situations.
i.e.: a, b, c = x #where x = [1, 2, 3]

PROPOSAL

* model
=======

This proposal favors the use of multiple values as inherent
to the language, rather than a seperate data-type.  It is
based on the observation that returning (multiple) values
is similar to passing arguments.  This fact is even more clear
when using continuations.

for example:
  x, y, z = mymethod(a, b, c)

  def mymethod
    return r1, r2, r3
  end

would mean this

  def mymethod
    callcc { |cc| cc.call(2, 3, 4) }
  end

  #(the following isn't legal syntax, but just to show the meaning)
  mymethod(a, b, c) |x, y, z|

basicly the expression:
  x, y, z = <expression returning multiple arguments>
will pass the multiple arguments to the given variables like
in function argument passing

The difference with argument passing in functions are the following:
- no new scope is created, bound variable are just replaced
- there is no strict checking if the number of arguments is
  correct

* new construct and method
==========================

- new construct:

because Array's are now treated different from multiple arguments
I would like to suggest the following construct
*[a, b] = [1, 2]

meaning the same as
  a, b = *[1, 2]
but usefull inside blocks that pass arrays

- new method:

(for now called values)
method returning multiple values as an array

def values(*params)
  params
end

values(1, 2, 4) => [1, 2, 4]

* variable assigment examples:
==============================

def multi
  return 1, 2, 3
end

#multi may be replaced everywhere with (1, 2, 3)

- variable asignment

x = multi
=> x == 1

x, y = multi
=> x == 1, y == 2

x, y = multi, 3
=> x == 1, y == 3

(x, y), z = multi, 4
=> x == 1, y == 2, z == 4

(*[x, y], z), p = ([1, 2, 3], 4, 5), 6
=> x == 1, y == 2, z == 4, p == 6

* calling to functions
======================

I would recommend the following behavior:

* when passing multiple values from one function to another,
  spread the values in a relaxed way (don't check the number
  of parameters).  When used with an explicit list, use
  strict checking.

    def func1(a) a end

    func1(multi)
    => 1

    func1(1, 2, 3)
    => error

    def func2(*a) a end

    func2(multi)
    => [1, 2, 3]
    
* when passing nested multiple variables just pass the first
  element

    def func3(a, b) [a, b] end

    func3(multi, 4)
    => [1, 4]

    func3((1, 2), 4)
    => [1, 4]
    #or maybe signal error?  not sure about this one

    func2(multi, 4)
    => [1, 4]

    func2(*values(multi), 4)
    => [1, 2, 3, 4]

* allow nested multiple values in method definitions

    def func4(a, (b, c), d)
      [a, b, c, d]
    end

    func4(1, 2, 3)
    => [1, 2, nil, 3]
    #maybe raise an error?

    func4(1, (2, 3), 4)
    => [1, 2, 3, 4]

    func4(1, multi, 4)
    => [1, 1, 2, 4]

    def func5(a, *[b, c], d)

    func5(1, 2, 3)
    => [1, 2, nil, 3]

    func5(1, [2, 3], 4)
    => [1, 2, 3, 4]

    func5(1, (2, 3), 4)
    => [1, 2, nil, 4]
    # (what will happen here is only the 2 from (2, 3) will be passed
    # to func5, converted into an Array, and passed to b

* Making argument passing and multiple assignment more similar
==============================================================

There may be other features that could be passed from arguments
passing to multiple assignment, for example hash paramaters?
Other may not be appropriate (i.e. blocks).