```Multiple Values, Assignments and *Unifications*

This RCR is really nice.
The multiple assignment reminds me of Prolog's "unification" mechanism.
What about some further generalization ?

Why not a generalized "assign" operator ? Syntax:
assign term1, term2 [, term3 [, ...]]
And of course an "unify" operator, Syntax:
unify term1, term2 [, term3 [, ...]]

The difference between "unify" and "assign" is only when
some lvalue exists already. In that case, unify checks that
the previous value is equal to the new value. If not, no assignment
is done at all. Whereas "assign" always assigns.
Another difference is that "assign" is a short match (vs greedy for unify),
i.e. assign [a,b], [1,2,3] # 3 ignored.
i.e. assign [a,b,c], [1,2] # c ignored, not assigned anything, not even nil.

The operator = is kept as it is today,
left-terms         = right_term would be equivalent to
assign [left-terms], right-term

Result
def mymethod(); return 1, [2], 3 end # Returns an Array
a, b, c = mymethod         # => 3, a == 1, b == [2], c == 3
assign [a,[b]], mymethod   # => 2, a == 1, b == 2, c unchanged
assign [a,[],c], mymethod  # => false, [] instead of [2]
p unify [a,[2],3], mymethod  # => true
p unify r, mymethod        # => [1,[2],3]
p unify [a,_,_], mymethod  # => 1, _ means "ignore me"

Add tail recursion optimization and you become functional.
I guess that with some callcc(), backtracking could come too.

A key benefit of this proposal is that it does not change
the current semantic of returned values. As a result it is
fully backward compatible with existing source code.

Would this solution solve the issue that your RCR solves ?

Jean-Hugues

BTW: It is often said that operator = is unusal because it does
not apply to an object. It could, we would need a BoundVariable
class, close to a Bindind, but referencing a specific variable.

At 21:24 26/04/2004 +0900, you wrote:
>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).

-------------------------------------------------------------------------
Web:  http://hdl.handle.net/1030.37/1.1
Phone: +33 (0) 4 92 27 74 17

```