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:
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=
tax:
=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=
=20
 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 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.
 
 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
parent reply 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
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 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 "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 parent reply 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
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] -- 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 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 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 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 Juanjo Alvarez <juanjux gmail.com> writes:
Denis Koroskin Wrote:


 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.
Python has the special symbol "_" which is used exactly as a no-op (you could call it "foo" it you wanted, but "_" doesn't create new memory assignments) so you can expand arbitrary tuples without creating new symbols: a, b, c, _ = ('tuple', 'of', 'three') I like the proposal for D, but I fear it could be a source of bugs (you expect the tuple to expand to 4 values but silently is expanding to only 3, leaving the fourth unchangued).
Oct 07 2010
prev sibling next 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
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Juanjo Alvarez:

 Python has the special symbol "_" which is used exactly as
 a no-op (you could call it "foo" it you wanted, but "_"
 doesn't create new memory assignments) so you can expand
 arbitrary tuples without creating new symbols:
 
 a, b, c, _ = ('tuple', 'of', 'three')
This is false both in Python2 and Python3. In Python3 there is the syntax: a, *bc = ('tuple', 'of', 'three') That's semantically similar to the proposed D syntax: auto record(a, bc...) = record('tuple', 'of', 'three') Bye, bearophile
Oct 07 2010
parent reply Juanjo Alvarez <fake fakeemail.com> writes:
On Thu, 07 Oct 2010 15:14:12 -0400, bearophile 
<bearophileHUGS lycos.com> wrote:
 This is false both in Python2 and Python3.
What is exactly false on what I said?
 a, *bc = ('tuple', 'of', 'three')
Yes, that's the syntax for assignment of the remainder, I was speaking about *ignoring* the remainder without having it assigned to the last element which was one of the proposed effects in the message before mine's.
Oct 07 2010
parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Juanjo Alvarez wrote:
 On Thu, 07 Oct 2010 15:14:12 -0400, bearophile
 <bearophileHUGS lycos.com> wrote:
 This is false both in Python2 and Python3.
=20 =20 What is exactly false on what I said?
 python
Python 2.6.5 (r265:79063, Apr 1 2010, 05:28:39) [GCC 4.4.3 20100316 (prerelease)] on linux2 Type "help", "copyright", "credits" or "license" for more information.
 a, b, c, _ =3D ('tuple', 'of', 'three')
Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: need more than 3 values to unpack

Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Oct 08 2010
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Juanjo Alvarez:

 What is exactly false on what I said?
This syntax you have explained doesn't do what you think it does: a, b, c, _ = ('tuple', 'of', 'three') See: http://ideone.com/LG1De The _ is just the name of a normal identifier (in the interactive shell it refers to the last result). Bye, bearophile
Oct 08 2010
parent reply Juanjo Alvarez <fake fakeemail.com> writes:
On Fri, 08 Oct 2010 16:11:53 -0400, bearophile 
<bearophileHUGS lycos.com> wrote:
 This syntax you have explained doesn't do what you think it does:
 a, b, c, _ = ('tuple', 'of', 'three')
That was a typo, I meant to write: a, b, _ = ('tuple', 'of', 'three')
Oct 08 2010
parent Leandro Lucarella <luca llucax.com.ar> writes:
Juanjo Alvarez, el  9 de octubre a las 04:02 me escribiste:
 On Fri, 08 Oct 2010 16:11:53 -0400, bearophile
 <bearophileHUGS lycos.com> wrote:
This syntax you have explained doesn't do what you think it does:
a, b, c, _ = ('tuple', 'of', 'three')
That was a typo, I meant to write: a, b, _ = ('tuple', 'of', 'three')
Even then, the _ identifier is not special all :) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Me encanta el éxito; por eso prefiero el estado de progreso constante, con la meta al frente y no atrás. -- Ricardo Vaporeso. Punta del Este, Enero de 1918.
Oct 08 2010