## digitalmars.D - Tuple assignment

- Walter Bright <newshound2 digitalmars.com> Oct 06 2010
- Russel Winder <russel russel.org.uk> Oct 06 2010
- Walter Bright <newshound2 digitalmars.com> Oct 06 2010
- Walter Bright <newshound2 digitalmars.com> Oct 07 2010
- Pelle <pelle.mansson gmail.com> Oct 07 2010
- Brad Roberts <braddr puremagic.com> Oct 07 2010
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Oct 07 2010
- "Denis Koroskin" <2korden gmail.com> Oct 07 2010
- "Denis Koroskin" <2korden gmail.com> Oct 07 2010
- Pelle <pelle.mansson gmail.com> Oct 07 2010
- Leandro Lucarella <luca llucax.com.ar> Oct 07 2010
- Tomek =?UTF-8?B?U293acWEc2tp?= <just ask.me> Oct 07 2010

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

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

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

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

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

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

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

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

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

On 10/07/2010 08:08 AM, Walter Bright wrote:

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

On 10/7/10 3:55 CDT, Pelle wrote:On 10/07/2010 08:08 AM, Walter Bright wrote:

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

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

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