From: Kristof Bastiaensen Date: 2004-04-26T21:24:07+09:00 Subject: Semantics of Multiple Values 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 = 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).