K
Kristof Bastiaensen
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).
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).