www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Destructured Tuple Assignment

reply "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
I recall having seen an example of using some D magic (via mixin 
perhaps?) to realize tuple destructuring in assignments like

     magic(first, _, second) = expression.findSplit(separator);

somewhere. But I can't seem to find it right now.

References anyone?

BTW :I'm aware of Kenjis PR, which I am very much longing for ;)
May 15 2015
next sibling parent reply "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Friday, 15 May 2015 at 10:23:24 UTC, Per Nordlöw wrote:
 I recall having seen an example of using some D magic (via 
 mixin perhaps?) to realize tuple destructuring in assignments 
 like

     magic(first, _, second) = expression.findSplit(separator);
I found it: http://forum.dlang.org/thread/ubrngkdmyduepmfkhefp forum.dlang.org?page=1 I'm however still as frustrated because instead of having to specify tuple indexes explicitly as const result = expression.findSplit(separator); const first = result[0]; const second = result[2]; I instead have to write types explicitly (no type-inference) string first, _, second; // non-generic unstable type guess tie(first, _, second) = expression.findSplit(separator); or just as bad typeof(expression.findSplit(separator)[0]) first, _, second; tie(first, _, second) = expression.findSplit(separator); Can this be solved with a mixin somehow?
May 15 2015
parent reply "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Friday, 15 May 2015 at 10:46:32 UTC, Per Nordlöw wrote:
 Can this be solved with a mixin somehow?
To clarify, I want to be able to write let(first, _, second) = expression.findSplit(separator); without having to first declare `first`, `_` and `second`. I'm guessing the closest thing we can get in current D version is something like let(q{first, _, second}, expression.findSplit(separator)); right? Which might be good enough for now.
May 15 2015
parent "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Friday, 15 May 2015 at 11:04:24 UTC, Per Nordlöw wrote:
 I'm guessing the closest thing we can get in current D version 
 is something like

     let(q{first, _, second},
         expression.findSplit(separator));

 right?
Correction: I believe it must look like let!q{first, _, second}(expression.findSplit(separator)); or let!`first, _, second`(expression.findSplit(separator)); Is it possible to define a let that does what I want here? If so, could someone, pleeeze, help me write out a stub for this? I'm guessing something along the lines of mixin template let(string vars, Ts...) { import std.range: splitter; // declare variables in current scope. TODO do we need a mixin here? foreach (i, var; vars.splitter(`, `)) { mixin(Ts[i] ~ ` ` ~ var); } auto let(Tuple!Ts xs) { foreach (i, var; vars.splitter(`, `)) { mixin(Ts[i] ~ ` = ` ~ xs[i]); } } } unittest { let!q{first, _, second}(tuple(`first`, `_`, `second`)); } but this fails in many ways. Could someone, please help out here?
May 15 2015
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 15 May 2015 at 10:23:24 UTC, Per Nordlöw wrote:
 I recall having seen an example of using some D magic (via 
 mixin perhaps?) to realize tuple destructuring in assignments 
 like

     magic(first, _, second) = expression.findSplit(separator);

 somewhere. But I can't seem to find it right now.

 References anyone?

 BTW :I'm aware of Kenjis PR, which I am very much longing for ;)
Well there's always this, which is a bit ugly: typeof(expression) first, _, second; TypeTuple!(first, _, second) = expression.findSplit(separator); But of course the holy grail is being able to declare variables inline.
May 15 2015
prev sibling parent reply Artur Skawina via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
   import std.algorithm;

   template magicassign(A...) {
      void magicassign(B)(B b)  property {
         foreach(I, ref a; A)
            static if (!is(typeof(A[I]):typeof(null)))
               a = b[I];
      }
   }

   template let(string D) {
      mixin({
         enum sdsl = D.findSplit("=");
         mixin(`struct S { int `~sdsl[0]~`; }`);
         string code = `auto v = ` ~ sdsl[2] ~ `;`;
         foreach (I, _; typeof(S.tupleof))
            code ~= `auto ` ~ S.tupleof[I].stringof ~ ` = v[`~I.stringof~`]; `;
         return code;
      }());
   }

   void main(string[] args) {
      import std.stdio;

      string a, b;
      magicassign!(a, null, b) = args[1].findSplit("-");
      writeln(a);
      writeln(b);

      mixin let!q{ c, _, d = args[1].findSplit("-") };
      writeln(c);
      writeln(d);
   }

artur
May 15 2015
next sibling parent "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Friday, 15 May 2015 at 12:22:55 UTC, Artur Skawina wrote:
    import std.algorithm;

    template let(string D) {
       mixin({
          enum sdsl = D.findSplit("=");
          mixin(`struct S { int `~sdsl[0]~`; }`);
          string code = `auto v = ` ~ sdsl[2] ~ `;`;
          foreach (I, _; typeof(S.tupleof))
             code ~= `auto ` ~ S.tupleof[I].stringof ~ ` = 
 v[`~I.stringof~`]; `;
          return code;
       }());
    }
Thanks!
May 15 2015
prev sibling parent reply "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Friday, 15 May 2015 at 12:22:55 UTC, Artur Skawina wrote:
    template let(string D) {
       mixin({
          enum sdsl = D.findSplit("=");
          mixin(`struct S { int `~sdsl[0]~`; }`);
          string code = `auto v = ` ~ sdsl[2] ~ `;`;
          foreach (I, _; typeof(S.tupleof))
             code ~= `auto ` ~ S.tupleof[I].stringof ~ ` = 
 v[`~I.stringof~`]; `;
          return code;
       }());
    }
I added support for auto, const and immutable declarations at https://github.com/nordlow/justd/blob/master/ties.d#L96 which allows usage as mixin let!q{ auto i, d, s, c = tuple(42, 3.14, `pi`, 'x') }; mixin let!q{ const i, d, s, c = tuple(42, 3.14, `pi`, 'x') }; mixin let!q{ immutable i, d, s, c = tuple(42, 3.14, `pi`, 'x') }; :) See unittests for details
May 15 2015
parent "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Friday, 15 May 2015 at 13:40:01 UTC, Per Nordlöw wrote:
 I added support for auto, const and immutable declarations at

 https://github.com/nordlow/justd/blob/master/ties.d#L96
And support for ignoring `_` as a variable as: import std.algorithm.searching: findSplit; mixin let!q{ c, _, d = `11-12`.findSplit(`-`) }; static assert(__traits(compiles, c == c)); static assert(!__traits(compiles, _ == _)); // assert that it was ignored
May 15 2015