ruby picture

RCR 183: Allow parens around a single target variable in multiple val

Submitted by coreywangler (Tue Jan 06 04:01:07 UTC 2004)

Abstract

Allow parenthesis around a single target variable, meaning assign the first element of the corresponding sub-array.
This is a logical extension of the currently allowable syntax.

Problem

Current syntax for grouping target values in multiple value assignment is incomplete.

Proposal

Allow parens around a single target value, meaning assign the first element of the corresponding sub-array.
New behaviour...
  (a),b,c = [1,2],[3,4],[5,6]
  ==> a=1, b=[3,4], c=[5,6]
  ((a),(b,c),d) = [[1,2,3],[4,5,6],[7,8,9]]
  ==> a=1, b=4, c=5, d=[7,8,9]
  ((a),(b,c),d) = [1,2,3,4,5]
  ==> a=1, b=2, c=nil, d=3</pre>
...just as (b,c) assigns the first and second elements of the corresponding sub-array to b and c respectively and ignores any remaining elements of that sub-array, (a) should similarly assign the first element of the corresponding sub-array to the target value a and ignore the other elements of that sub-array.


ASIDE:
Note that the following multi-value assignments all mean the same thing, as (in my thinking) omitting the outer parens (on LHS) or brackets [on RHS] is allowed in a similar way to that which parens can be omitted from method calls (thus conforming to the "principle of least surprise")...

    

    
  def foo
    return [1,2],[3,4],[5,6]   #returns an Array [[1,2],[3,4],[5,6]]
  end
   (a),b,c  =  foo
  ((a),b,c) =  foo
  ((a),b,c) = [[1,2],[3,4],[5,6]]
  ((a),b,c) =  [1,2],[3,4],[5,6]
   (a),b,c  = [[1,2],[3,4],[5,6]]
   (a),b,c  =  [1,2],[3,4],[5,6]
  #all of these give ==> a=1, b=[3,4], c=[5,6]</pre>

So Matz, I recon the current behaviour is correct ("semantics on multiple values" in Ruby 2)...

    

    
  x = [1,2,3]
  a, b, c = x
  ==> a=1, b=2, c=3</pre>
...as the programmer can think of it as allowing outer parens and brackets to be omitted. i.e.

    

    
  x = 1,2,3     same as saying    x = [1,2,3]

...and...
  a,b,c = x     same as saying    (a,b,c) = x</pre>

  

Analysis

This proposal is a logical extension of existing syntax, and makes multiple value assignment a more powerful language construct.

Will not break current code, as this is new syntax.

Implementation

Language modification is required.
ruby picture
Comments Current voting

Do you know the proposed feature is already implemented in the current Ruby with trailing comma?, i.e.

  (a,),b,c = [1,2],[3,4],[5,6]
  ==> a=1, b=[3,4], c=[5,6]

I thought the trailing comma is useful to distinguish mere grouping parentheses and multiple assignment targets.

-matz.

Extra comma surprising to me

No, I did not know that a trailing comma would do that. To me that syntax (trailing comma) is rather surprising. But I'm just a noobie to ruby :)

When looking at writing the multiple assignment target I think in terms of making it look like the array from which the values would be assigned. It seems messy to me to have to add that trailing comma, especially where the corresponding element might only have one value in that sub-array.

To me, POLS would be to have (a) as valid syntax, because the representation of the target syntax then becomes exactly the same as that for array syntax, apart from the different types of brackets.

  ((a),(b,c),(d,e,f)) = [[1],[2,3],[4,5,6]]
  ==> a=1, b=2, c=3, d=4, e=5, f=6

Any comments on this line of thinking?

Don't mention POLS again in the RCR ;-)

I can understand your feeling, but don't forget parentheses are often treated as mere grouping which should not have no other effect.

For example, decompose multiple assignment in your proposal:

  (a),b,c = [1,2],[3,4],[5,6]

would be

  (a) = [1,2]
  b = [2,3]
  c = [4,5,6]

what do you expect for the value of a? I expect a to be [1,2], not 1 as in your example. That's why I made traling comma mandatory, like

 (a,) = [1,2]
  b = [2,3]
  c = [4,5,6]

-matz.

Yeah, trailing comma is better - withdrawing RCR

Looking at something like this...

  a, = [1,2],[3,4],[5,6]
  ==> a=[1,2]

...and...

  (a,) = [[1,2],[3,4],[5,6]]
  ==> a=[1,2]

...and...

  x=[ [[1,2],[3,4]], [[5,6],[7,8]] ]
   (g,),(h,)   = x
   (g,),(h,),  = x
  ((g,),(h,))  = x
  ((g,),(h,),) = x
  ==> g=[1,2] h=[5,6]  # all forms are equivalent

...convinces me that the current implementation is better than my suggestion, because it makes it clear that you want just an element from that level of nesting, and also allows for use with omitted outer parens.

Thanks Matz! -Corey.


Strongly opposed 0
Opposed 2
Neutral 0
In favor 0
Strongly advocate 0
ruby picture

This RCR supersedes RCR 182.

If you have registered at RCRchive, you may now sign in below. If you have not registered, you may sign up for a username and password. Registering enables you to submit new RCRs, and vote and leave comments on existing RCRs.
Your username:
Your password:

ruby picture

Powered by .