www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Tuple assignment

reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
Python has tuple assignment so you see things like:

        previous, current =3D current, previous + current

especially if you are doing silly things like calculating Fibonacci
Sequence values. Translating this to D, you end up with:

        TypeTuple!(current, next) =3D tuple(next , current +next);

I am assuming this is horrendously inefficient at run time compared to
having the intermediate value explicit:

        auto t =3D next;
        next =3D current + next;
        current =3D t;

or is it?=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 winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder
May 09 2015
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/9/2015 10:16 AM, Russel Winder via Digitalmars-d wrote:
 Python has tuple assignment so you see things like:

          previous, current = current, previous + current

 especially if you are doing silly things like calculating Fibonacci
 Sequence values. Translating this to D, you end up with:

          TypeTuple!(current, next) = tuple(next , current +next);

 I am assuming this is horrendously inefficient at run time compared to
 having the intermediate value explicit:

          auto t = next;
          next = current + next;
          current = t;

 or is it?
It probably depends on the compiler. The way to find out is to look at the generated assembler. Tuples are implemented as structs. I know that ldc is capable of slicing structs into register-sized pieces and optimizing them independently, dmd does not. So ldc would very possibly generate the kind of code for that that you'd like.
May 09 2015
next sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 2015-05-09 at 13:07 -0700, Walter Bright via Digitalmars-d wrote:
 [=E2=80=A6]
 It probably depends on the compiler. The way to find out is to look=20
 at the=20
 generated assembler.
<pedant-mode>assembly language file, not assembler (which is the program to do the transformation)</pedant-mode> ldc2 and gdc have options to write the assembly language file, maybe I am missing it but dmd appears not to advertise such an option.
 Tuples are implemented as structs. I know that ldc is capable of=20
 slicing structs=20
 into register-sized pieces and optimizing them independently, dmd=20
 does not. So=20
 ldc would very possibly generate the kind of code for that that=20
 you'd like.
I shall investigate with gdc as well as ldc. Though, sadly, whilst gdc is in Debian it is not in Fedora. :-( --=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 winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
May 10 2015
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 5/10/2015 1:07 AM, Russel Winder via Digitalmars-d wrote:
 ldc2 and gdc have options to write the assembly language file, maybe I
 am missing it but dmd appears not to advertise such an option.
http://www.digitalmars.com/ctg/obj2asm.html
May 10 2015
prev sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Sunday, 10 May 2015 at 08:07:38 UTC, Russel Winder wrote:
 On Sat, 2015-05-09 at 13:07 -0700, Walter Bright via 
 Digitalmars-d wrote:
 […]
 It probably depends on the compiler. The way to find out is to 
 look at the generated assembler.
<pedant-mode>assembly language file, not assembler (which is the program to do the transformation)</pedant-mode> ldc2 and gdc have options to write the assembly language file, maybe I am missing it but dmd appears not to advertise such an option.
What's wrong with objdump?
May 10 2015
parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 10 May 2015 at 21:41, John Colvin via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Sunday, 10 May 2015 at 08:07:38 UTC, Russel Winder wrote:
 On Sat, 2015-05-09 at 13:07 -0700, Walter Bright via Digitalmars-d wrote:
 […]
 It probably depends on the compiler. The way to find out is to look at
 the generated assembler.
<pedant-mode>assembly language file, not assembler (which is the program to do the transformation)</pedant-mode> ldc2 and gdc have options to write the assembly language file, maybe I am missing it but dmd appears not to advertise such an option.
What's wrong with objdump?
Assembly has more information, such as .align and .loc directives. ;-)
May 10 2015
prev sibling next sibling parent "weaselcat" <weaselcat gmail.com> writes:
On Saturday, 9 May 2015 at 20:07:00 UTC, Walter Bright wrote:
 It probably depends on the compiler. The way to find out is to 
 look at the generated assembler.
fwiw, I tried to look at this earlier and found out a single tuple generates too much assembly for asm.dlang.org to display ;)
May 10 2015
prev sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 2015-05-09 at 13:07 -0700, Walter Bright via Digitalmars-d wrote:
 On 5/9/2015 10:16 AM, Russel Winder via Digitalmars-d wrote:
 Python has tuple assignment so you see things like:
=20
          previous, current =3D current, previous + current
=20
 especially if you are doing silly things like calculating Fibonacci
 Sequence values. Translating this to D, you end up with:
=20
          TypeTuple!(current, next) =3D tuple(next , current +next);
=20
 I am assuming this is horrendously inefficient at run time=20
 compared to
 having the intermediate value explicit:
=20
          auto t =3D next;
          next =3D current + next;
          current =3D t;
=20
 or is it?
=20 It probably depends on the compiler. The way to find out is to look=20 at the=20 generated assembler.
Using LDC, the tuple version generates more code unoptimized, but with optimization, the exact same assembly language code is generated for the two cases. Win.=20 Albeit the D syntax is not as nice as the Python syntax. --=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 winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
May 10 2015
parent Walter Bright <newshound2 digitalmars.com> writes:
On 5/10/2015 1:18 AM, Russel Winder via Digitalmars-d wrote:
 Using LDC, the tuple version generates more code unoptimized, but with
 optimization, the exact same assembly language code is generated for
 the two cases.

 Win.
This is what makes D's ranges+algorithms so attractive. They are easier to write correct code in, and when optimized produce the same code.
May 10 2015
prev sibling parent reply "Oren Tirosh" <orent hishome.net> writes:
On Saturday, 9 May 2015 at 17:16:58 UTC, Russel Winder wrote:
 Python has tuple assignment so you see things like:

         previous, current = current, previous + current

 especially if you are doing silly things like calculating 
 Fibonacci
 Sequence values. Translating this to D, you end up with:

         TypeTuple!(current, next) = tuple(next , current +next);
This works right now and is quite aesthetically pleasing: tuple(current, next) = tuple(next , current +next); Note, however, that this is not a tuple assignment. It is assignment of a misleadingly-named anonymous struct type that is implemented in the standard library. This is an actual tuple assignment as supported by the compiler: a.tupleof = b.tupleof; I think it should work for any two structs as long their fields are public and individually assignment-compatible. I believe it is as efficient as individual assignments on all D implementations. A lot of people seem to want better sugar for tuple or tuple-like things in D and do not consider std.typecons sufficient (or at least find the names it uses confusing). Such a feature would work very nicely with D's auto types, return and lambda argument type inference, etc. See LINQ.
May 10 2015
next sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 2015-05-10 at 08:14 +0000, Oren Tirosh via Digitalmars-d wrote:
 On Saturday, 9 May 2015 at 17:16:58 UTC, Russel Winder wrote:
=20
[=E2=80=A6]
         TypeTuple!(current, next) =3D tuple(next , current +next);
This works.
 This works right now and is quite aesthetically pleasing:
=20
      tuple(current, next) =3D tuple(next , current +next);
This does not. At least the tests fail with this where they do not with the previous.
 [=E2=80=A6]
--=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 winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
May 10 2015
parent reply "Oren Tirosh" <orent hishome.net> writes:
On Sunday, 10 May 2015 at 08:28:24 UTC, Russel Winder wrote:
 On Sun, 2015-05-10 at 08:14 +0000, Oren Tirosh via 
 Digitalmars-d wrote:
 On Saturday, 9 May 2015 at 17:16:58 UTC, Russel Winder wrote:
 
[…]
         TypeTuple!(current, next) = tuple(next , current 
 +next);
This works.
I did not mean imply that it doesn't, just that what I wrote is not some proposed syntax for tuple assignment but something that actually works now.
 This works right now and is quite aesthetically pleasing:
 
      tuple(current, next) = tuple(next , current +next);
This does not. At least the tests fail with this where they do not with the previous.
Works for me. If this is version or compiler dependent this definitely needs investigation.
May 10 2015
parent Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 2015-05-10 at 08:47 +0000, Oren Tirosh via Digitalmars-d wrote:
=20
[=E2=80=A6]
      tuple(current, next) =3D tuple(next , current +next);
=20
[=E2=80=A6]
 Works for me. If this is version or compiler dependent this=20
 definitely needs investigation.
It does not for me using rdmd 2.067. My implementation of nth Fibonacci Number leads to success for my version but not for yours. Maybe we should exchange codes offlist? =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 winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
May 10 2015
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2015-05-10 10:14, Oren Tirosh wrote:

 I think it should work for any two structs as long their fields are
 public and individually assignment-compatible.
Just for the record, "tupleof" bypasses protection. -- /Jacob Carlborg
May 11 2015