www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Tuple assignment

reply Walter Bright <newshound2 digitalmars.com> writes:
If expr represents a tuple, we (Andrei and I) were thinking about the syntax:

     auto (a, b, c, d) = expr;

being equivalent to:

     auto t = expr; auto a = t[0]; auto b = t[1]; auto c = t[2 .. $];

You can also do this with arrays, such that:

     float[3] xyz;
     auto (x, y, z) = xyz;

The Lithpers among you will notice that this essentially provides a handy 
car,cdr shortcut for tuples and arrays:

     auto (car, cdr) = expr;
Oct 06 2010
next sibling parent reply Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, 2010-10-06 at 23:08 -0700, Walter Bright wrote:
 If expr represents a tuple, we (Andrei and I) were thinking about the syn=

=20
      auto (a, b, c, d) =3D expr;
=20
 being equivalent to:
=20
      auto t =3D expr; auto a =3D t[0]; auto b =3D t[1]; auto c =3D t[2 ..=

=20
 You can also do this with arrays, such that:
=20
      float[3] xyz;
      auto (x, y, z) =3D xyz;
=20
 The Lithpers among you will notice that this essentially provides a handy=

 car,cdr shortcut for tuples and arrays:
=20
      auto (car, cdr) =3D expr;

Python may be the best base to compare things to as tuple assignment has been in there for years. Pythons choice is not a car/cdr approach but an exact match approach. so if t represents a tuple datum or a function returning a tuple: x =3D t then x is a tuple -- remembering that variables are all just references to objects implemented via keys in a dictionary, and: a , b , c =3D t or ( a , b , c ) =3D t is tuple assignment where now t is required to be a tuple of length 3. cf. |> python Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)=20 [GCC 4.4.3] on linux2 Type "help", "copyright", "credits" or "license" for more informati= on. >>> t =3D ( 1 , 'fred' , 2.0 ) >>> x =3D t >>> print x (1, 'fred', 2.0) >>> a , b , c =3D t >>> print a , b , c 1 fred 2.0 >>> a , b =3D t Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: too many values to unpack >>> a , b , c , d =3D t Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: need more than 3 values to unpack >>>=20 --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Oct 06 2010
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
Russel Winder wrote:
 Python may be the best base to compare things to as tuple assignment has
 been in there for years.
 
 Pythons choice is not a car/cdr approach but an exact match approach.
 so if t represents a tuple datum or a function returning a tuple:
 
         x = t
 
 then x is a tuple -- remembering that variables are all just references
 to objects implemented via keys in a dictionary, and:
 
         a , b , c = t
 or
         ( a , b , c ) = t
 
 is tuple assignment where now t is required to be a tuple of length 3.
 cf.

The first thought was to make it an exact match approach. Andrei thought that the car/cdr one was better, though, and I find it intuitively appealing, too. Perhaps Python missed an important use case? Or perhaps the ambiguity as to whether the last item gets to be a value or another tuple is too much.
Oct 06 2010
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Russel Winder wrote:
 Python may be the best base to compare things to as tuple assignment has
 been in there for years.

Too segue this into the previous thread, how does Python treat (1)? Is it a floor wax or a dessert topping? http://www.nbc.com/saturday-night-live/video/shimmer-floor-wax/1056743/
Oct 07 2010
parent Pelle <pelle.mansson gmail.com> writes:
On 10/07/2010 09:03 AM, Walter Bright wrote:
 Russel Winder wrote:
 Python may be the best base to compare things to as tuple assignment has
 been in there for years.

Too segue this into the previous thread, how does Python treat (1)? Is it a floor wax or a dessert topping? http://www.nbc.com/saturday-night-live/video/shimmer-floor-wax/1056743/

(1) == 1 (1,) == tuple([1])
Oct 07 2010
prev sibling next sibling parent Brad Roberts <braddr puremagic.com> writes:
On 10/6/2010 11:58 PM, Walter Bright wrote:
 Russel Winder wrote:
 Python may be the best base to compare things to as tuple assignment has
 been in there for years.

 Pythons choice is not a car/cdr approach but an exact match approach.
 so if t represents a tuple datum or a function returning a tuple:

         x = t

 then x is a tuple -- remembering that variables are all just references
 to objects implemented via keys in a dictionary, and:

         a , b , c = t
 or
         ( a , b , c ) = t

 is tuple assignment where now t is required to be a tuple of length 3.
 cf.

The first thought was to make it an exact match approach. Andrei thought that the car/cdr one was better, though, and I find it intuitively appealing, too. Perhaps Python missed an important use case? Or perhaps the ambiguity as to whether the last item gets to be a value or another tuple is too much.

I think the ambiguity should be avoided. There was one language I used ages ago that used a token to signal the use of the last arg as a 'rest' usage. If I remember right, it used: (a, b) = aggregate; // a = aggregate[0], b = aggregate[1..$] It also allowed: (a, aggregate) = aggregate; // essentially a pop operation. That said, it was a weakly typed language, so it's application to D has to be taken with an appropriate dose of salt. For D, I think using the would clash badly with the attribute syntax, so an alternative that's not horrid: (a, b...) = aggregate; Later, Brad
Oct 07 2010
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/7/10 1:43 CDT, Russel Winder wrote:
 On Wed, 2010-10-06 at 23:08 -0700, Walter Bright wrote:
 If expr represents a tuple, we (Andrei and I) were thinking about the syntax:

       auto (a, b, c, d) = expr;

 being equivalent to:

       auto t = expr; auto a = t[0]; auto b = t[1]; auto c = t[2 .. $];

 You can also do this with arrays, such that:

       float[3] xyz;
       auto (x, y, z) = xyz;

 The Lithpers among you will notice that this essentially provides a handy
 car,cdr shortcut for tuples and arrays:

       auto (car, cdr) = expr;

Python may be the best base to compare things to as tuple assignment has been in there for years. Pythons choice is not a car/cdr approach but an exact match approach.

So then we'd have the proposed notation not work with dynamic arrays - only with static arrays and tuples. Andrei
Oct 07 2010
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Thu, 07 Oct 2010 10:43:18 +0400, Russel Winder <russel russel.org.uk>  
wrote:

 On Wed, 2010-10-06 at 23:08 -0700, Walter Bright wrote:
 If expr represents a tuple, we (Andrei and I) were thinking about the  
 syntax:

      auto (a, b, c, d) = expr;

 being equivalent to:

      auto t = expr; auto a = t[0]; auto b = t[1]; auto c = t[2 .. $];

 You can also do this with arrays, such that:

      float[3] xyz;
      auto (x, y, z) = xyz;

 The Lithpers among you will notice that this essentially provides a  
 handy
 car,cdr shortcut for tuples and arrays:

      auto (car, cdr) = expr;

Python may be the best base to compare things to as tuple assignment has been in there for years. Pythons choice is not a car/cdr approach but an exact match approach. so if t represents a tuple datum or a function returning a tuple: x = t then x is a tuple -- remembering that variables are all just references to objects implemented via keys in a dictionary, and: a , b , c = t or ( a , b , c ) = t is tuple assignment where now t is required to be a tuple of length 3. cf. |> python Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) [GCC 4.4.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> t = ( 1 , 'fred' , 2.0 ) >>> x = t >>> print x (1, 'fred', 2.0) >>> a , b , c = t >>> print a , b , c 1 fred 2.0 >>> a , b = t Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: too many values to unpack >>> a , b , c , d = t Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: need more than 3 values to unpack >>>

That's because Python is not a strictly typed language. With proper type propagation compiler helps you writing code the way in meant to be. E.g. the following: (a, b, c, d) = ('tuple', 'of', 'three') could be statically disabled, but there is nothing wrong with allowing it either: d would be just a no-op, you will know it for sure the moment you try using it.
Oct 07 2010
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Thu, 07 Oct 2010 11:42:06 +0400, Brad Roberts <braddr puremagic.com>  
wrote:

 On 10/6/2010 11:58 PM, Walter Bright wrote:
 Russel Winder wrote:
 Python may be the best base to compare things to as tuple assignment  
 has
 been in there for years.

 Pythons choice is not a car/cdr approach but an exact match approach.
 so if t represents a tuple datum or a function returning a tuple:

         x = t

 then x is a tuple -- remembering that variables are all just references
 to objects implemented via keys in a dictionary, and:

         a , b , c = t
 or
         ( a , b , c ) = t

 is tuple assignment where now t is required to be a tuple of length 3.
 cf.

The first thought was to make it an exact match approach. Andrei thought that the car/cdr one was better, though, and I find it intuitively appealing, too. Perhaps Python missed an important use case? Or perhaps the ambiguity as to whether the last item gets to be a value or another tuple is too much.

I think the ambiguity should be avoided. There was one language I used ages ago that used a token to signal the use of the last arg as a 'rest' usage. If I remember right, it used: (a, b) = aggregate; // a = aggregate[0], b = aggregate[1..$] It also allowed: (a, aggregate) = aggregate; // essentially a pop operation. That said, it was a weakly typed language, so it's application to D has to be taken with an appropriate dose of salt. For D, I think using the would clash badly with the attribute syntax, so an alternative that's not horrid: (a, b...) = aggregate; Later, Brad

Interesting idea, I like it!
Oct 07 2010
prev sibling next sibling parent reply Pelle <pelle.mansson gmail.com> writes:
On 10/07/2010 08:08 AM, Walter Bright wrote:
 If expr represents a tuple, we (Andrei and I) were thinking about the
 syntax:

 auto (a, b, c, d) = expr;

 being equivalent to:

 auto t = expr; auto a = t[0]; auto b = t[1]; auto c = t[2 .. $];

 You can also do this with arrays, such that:

 float[3] xyz;
 auto (x, y, z) = xyz;

 The Lithpers among you will notice that this essentially provides a
 handy car,cdr shortcut for tuples and arrays:

 auto (car, cdr) = expr;

Python 3 uses: car, *cdr = expr a, *b, c = [1,2,3,4,5] # leaves a=1, b=[2,3,4], c=5 I would like D to have (car, cdr...) = expr (a, b..., c) = [1,2,3,4,5] for the equivalent. Our varargs syntax is b..., theirs is *b. So it mirrors a bit, there. :-)
Oct 07 2010
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/7/10 3:55 CDT, Pelle wrote:
 On 10/07/2010 08:08 AM, Walter Bright wrote:
 If expr represents a tuple, we (Andrei and I) were thinking about the
 syntax:

 auto (a, b, c, d) = expr;

 being equivalent to:

 auto t = expr; auto a = t[0]; auto b = t[1]; auto c = t[2 .. $];

 You can also do this with arrays, such that:

 float[3] xyz;
 auto (x, y, z) = xyz;

 The Lithpers among you will notice that this essentially provides a
 handy car,cdr shortcut for tuples and arrays:

 auto (car, cdr) = expr;

Python 3 uses: car, *cdr = expr a, *b, c = [1,2,3,4,5] # leaves a=1, b=[2,3,4], c=5 I would like D to have (car, cdr...) = expr (a, b..., c) = [1,2,3,4,5] for the equivalent. Our varargs syntax is b..., theirs is *b. So it mirrors a bit, there. :-)

Excellent idea! Andrei
Oct 07 2010
prev sibling next sibling parent Leandro Lucarella <luca llucax.com.ar> writes:
Andrei Alexandrescu, el  7 de octubre a las 03:20 me escribiste:
 On 10/7/10 1:43 CDT, Russel Winder wrote:
On Wed, 2010-10-06 at 23:08 -0700, Walter Bright wrote:
If expr represents a tuple, we (Andrei and I) were thinking about the syntax:

      auto (a, b, c, d) = expr;

being equivalent to:

      auto t = expr; auto a = t[0]; auto b = t[1]; auto c = t[2 .. $];



I guess d being missing is a typo, right?
You can also do this with arrays, such that:

      float[3] xyz;
      auto (x, y, z) = xyz;

The Lithpers among you will notice that this essentially provides a handy
car,cdr shortcut for tuples and arrays:

      auto (car, cdr) = expr;

Python may be the best base to compare things to as tuple assignment has been in there for years. Pythons choice is not a car/cdr approach but an exact match approach.

So then we'd have the proposed notation not work with dynamic arrays - only with static arrays and tuples.

Unless you add a dynamic "bound" check as when accessing a dynamic array item, something like: auto t = expr; assert (t.lenght == 4); auto a = t[0]; auto b = t[1]; auto c = t[2]; auto d = t[3]; I like the idea of having exact match approach and the explicit syntax for getting the rest as Brad said. But in all the years I used Python, I never needed that syntax, maybe because most of the times when I use the tuple expansion I know the size or I want to truncate, or I use something to generate the data, like split(), that takes an extra parameter to do that: l = [1, 2, 3] a, b, c = l # known lenght a, b = l[:2] # truncation (like l[0..2] in D) a, b = '1,2,3'.split(',', 1) # get the rest in b (but it will be a string) car, cdr = l[0], l[1:] # just a little more verbose -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- careful to all animals (never washing spiders down the plughole), keep in contact with old friends (enjoy a drink now and then), will frequently check credit at (moral) bank (hole in the wall),
Oct 07 2010
prev sibling parent Tomek =?UTF-8?B?U293acWEc2tp?= <just ask.me> writes:
Walter Bright napisaƂ:

 If expr represents a tuple, we (Andrei and I) were thinking about the
 syntax:
 
      auto (a, b, c, d) = expr;
 
 being equivalent to:
 
      auto t = expr; auto a = t[0]; auto b = t[1]; auto c = t[2 .. $];

Typo? If not, what is 'd'? Either way, I'd like mismatching tuple lengths to fail, not assign the tail to the last variable. Or, as pelle brought up: auto (a, b..., c) = expr, where b = expr[1..2] and you may have only one ... in the lhs. It's not bad.
 You can also do this with arrays, such that:
 
      float[3] xyz;
      auto (x, y, z) = xyz;

 The Lithpers among you will notice that this essentially provides a handy
 car,cdr shortcut for tuples and arrays:
 
      auto (car, cdr) = expr;

Nice. It's all nice but as my colleague once said: put it on the todo list right after 'learn Portugese'. -- Tomek
Oct 07 2010