Destructured Tuple Assignment

2015-05-15 Thread via Digitalmars-d-learn
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 ;)


Re: Destructured Tuple Assignment

2015-05-15 Thread Artur Skawina via Digitalmars-d-learn
   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


Re: Destructured Tuple Assignment

2015-05-15 Thread via Digitalmars-d-learn

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?


Re: Destructured Tuple Assignment

2015-05-15 Thread John Colvin via Digitalmars-d-learn

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.


Re: Destructured Tuple Assignment

2015-05-15 Thread via Digitalmars-d-learn

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/ubrngkdmyduepmfkh...@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?


Re: Destructured Tuple Assignment

2015-05-15 Thread via Digitalmars-d-learn

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.


Re: Destructured Tuple Assignment

2015-05-15 Thread via Digitalmars-d-learn

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


Re: Destructured Tuple Assignment

2015-05-15 Thread via Digitalmars-d-learn

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!


Re: Destructured Tuple Assignment

2015-05-15 Thread via Digitalmars-d-learn

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