Re: Checking template parameter types of class

2015-05-25 Thread Ali Çehreli via Digitalmars-d-learn

On 05/24/2015 09:14 PM, tcak wrote:

 Line 243: auto fileResourceList = new shared FileResourceList( 2
 );

 main.d(243): Error: class main.FileResourceList(T) if (is(T :
 FileResource)) is used as a type

struct and class templates do not have automatic type deduction; 
function templates do. The solution is to provide a convenience function 
template alongside the struct or class.


 auto fileResourceList = new shared FileResourceList!FileResource( 2 );

 Then it works. The error message is not indicating directly this, though
 logically it is still correct.

'if (is(T : FileResource))' part means if T can implicitly be converted 
to FileResource. You still provide T so that it gets checked.


Ali



Re: Checking template parameter types of class

2015-05-25 Thread thedeemon via Digitalmars-d-learn

On Monday, 25 May 2015 at 04:15:00 UTC, tcak wrote:


main.d(243): Error: class main.FileResourceList(T) if (is(T :
FileResource)) is used as a type


The error message is not indicating directly this, though 
logically it is still correct.


Compiler means template is used as a type which is an error 
since templates are not types. I guess adding the word template 
to that message would make it more clear.


Re: Idiomatic way to call base method in generic code

2015-05-25 Thread ketmar via Digitalmars-d-learn
On Sun, 24 May 2015 23:32:50 +, ZombineDev wrote:

 I know I can call a base implementation of a method like in 3), but I
 need to do it generically like in 2). Does anybody now how I can achieve
 this?

i don't know why you want that, but something like this may do:

auto callBaseMethod(string MTN, C, Args...) (inout C self, Args args) {
  alias FSC = BaseClassesTuple!(C)[0];
  return mixin(`self.`~FSC.stringof~`.`~MTN~(args));
}

writeln(d.callBaseMethod!toString);


 Additionally is there a way to make 1) work without using string mixins?

no. and again, why do you want that? why do you people are so afraid of 
string mixins? ;-)

signature.asc
Description: PGP signature


Re: Idiomatic way to call base method in generic code

2015-05-25 Thread ZombineDev via Digitalmars-d-learn

On Monday, 25 May 2015 at 07:57:49 UTC, ketmar wrote:

i don't know why you want that, but something like this may do:

auto callBaseMethod(string MTN, C, Args...) (inout C self, Args 
args) {

  alias FSC = BaseClassesTuple!(C)[0];
  return mixin(`self.`~FSC.stringof~`.`~MTN~(args));
}

writeln(d.callBaseMethod!toString);



Thanks!

[1]: 
https://github.com/ZombineDev/Chess2RT/blob/c36ba3e73744cf3912c25abccedbbd742f7f5be3/source/util/prettyprint.d#L7


[2]: 
https://github.com/ZombineDev/Chess2RT/blob/master/source/util/prettyprint.d#L14


I initially had [1] a string mixin which goes through all the 
members of a class and prints them and also prints its base 
class' members, but then it seemed that it would be more cleaner 
if I could use a function template [2] (which also improved my 
debug experience) so I started exploring alias, but they turned 
out to be less powerful then I thought:


alias can't refer to a nested member:
-
struct Point2
{
float x;
float y;
}

struct Line2
{
Point2 start;
Point2 end;

mixin Access;

// alias x1 = this.start.x; - this doesn't work :(

alias x1 = get!start.x;
alias y1 = get!start.y;
alias x2 = get!end.x;
alias y2 = get!end.y;
}

// I need to use a mixin to flatten the access :(
private mixin template Access()
{
ref auto get(string accessPattern)() inout
{
return mixin(accessPattern);
}
}
-

So I wondered if I'm missing something and decided to ask here.

no. and again, why do you want that? why do you people are so 
afraid of

string mixins? ;-)


Well I'm not afraid of string mixins, but the `alias` keyword 
seemed to possess some mysterious power (I was also under the 
influence of this [3] blog post) which I wanted to explore. Also 
they're a bit more elegant.


[3]: 
http://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/




Regex-Fu

2015-05-25 Thread Chris via Digitalmars-d-learn
I'm a bit at a loss here. I cannot get the longest possible 
match. I tried several versions with eager operators and stuff, 
but D's regex engine(s) always seem to return the shortest match. 
Is there something embarrassingly simple I'm missing?


void main()
{
  import std.regex : regex, matchFirst;
  import std.stdio : writeln;

  auto word = blablahula;
  auto m = matchFirst(word, regex(^([a-z]+)(hula|ula)$));
  writeln(m);  // prints [blablahula, blablah, ula]
}

I want it to return hula not ula.


Re: Regex-Fu

2015-05-25 Thread novice2 via Digitalmars-d-learn

I cannot get the longest possible

it match longest for first group ([a-z]+)

try

^([a-z]+?)(hula|ula)$



Re: Regex-Fu

2015-05-25 Thread Chris via Digitalmars-d-learn

On Monday, 25 May 2015 at 11:20:46 UTC, novice2 wrote:

I cannot get the longest possible

it match longest for first group ([a-z]+)

try

^([a-z]+?)(hula|ula)$


Namespace, novice2:

Ah, I see. The problem was with the first group that was too 
greedy, not with the second. I was focusing on the latter. 
Thanks, this works now!


Re: Regex-Fu

2015-05-25 Thread Namespace via Digitalmars-d-learn

On Monday, 25 May 2015 at 11:11:50 UTC, Chris wrote:
I'm a bit at a loss here. I cannot get the longest possible 
match. I tried several versions with eager operators and stuff, 
but D's regex engine(s) always seem to return the shortest 
match. Is there something embarrassingly simple I'm missing?


void main()
{
  import std.regex : regex, matchFirst;
  import std.stdio : writeln;

  auto word = blablahula;
  auto m = matchFirst(word, regex(^([a-z]+)(hula|ula)$));
  writeln(m);  // prints [blablahula, blablah, ula]
}

I want it to return hula not ula.


Make the + operator less greedy:

matchFirst(word, regex(^([a-z]+?)(hula|ula)$));


Re: Idiomatic way to call base method in generic code

2015-05-25 Thread Meta via Digitalmars-d-learn

On Monday, 25 May 2015 at 09:24:58 UTC, ZombineDev wrote:

On Monday, 25 May 2015 at 07:57:49 UTC, ketmar wrote:

i don't know why you want that, but something like this may do:

auto callBaseMethod(string MTN, C, Args...) (inout C self, 
Args args) {

 alias FSC = BaseClassesTuple!(C)[0];
 return mixin(`self.`~FSC.stringof~`.`~MTN~(args));
}

writeln(d.callBaseMethod!toString);



Thanks!

[1]: 
https://github.com/ZombineDev/Chess2RT/blob/c36ba3e73744cf3912c25abccedbbd742f7f5be3/source/util/prettyprint.d#L7


[2]: 
https://github.com/ZombineDev/Chess2RT/blob/master/source/util/prettyprint.d#L14


I initially had [1] a string mixin which goes through all the 
members of a class and prints them and also prints its base 
class' members, but then it seemed that it would be more 
cleaner if I could use a function template [2] (which also 
improved my debug experience) so I started exploring alias, but 
they turned out to be less powerful then I thought:


alias can't refer to a nested member:
-
struct Point2
{
float x;
float y;
}

struct Line2
{
Point2 start;
Point2 end;

mixin Access;

// alias x1 = this.start.x; - this doesn't work :(

alias x1 = get!start.x;
alias y1 = get!start.y;
alias x2 = get!end.x;
alias y2 = get!end.y;
}

// I need to use a mixin to flatten the access :(
private mixin template Access()
{
ref auto get(string accessPattern)() inout
{
return mixin(accessPattern);
}
}
-

So I wondered if I'm missing something and decided to ask here.

no. and again, why do you want that? why do you people are so 
afraid of

string mixins? ;-)


Well I'm not afraid of string mixins, but the `alias` keyword 
seemed to possess some mysterious power (I was also under the 
influence of this [3] blog post) which I wanted to explore. 
Also they're a bit more elegant.


[3]: 
http://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/


You might be interested in this thread:

http://forum.dlang.org/thread/mi3pip$22va$1...@digitalmars.com


Re: Replacing nested loops foreach using map/each/etc

2015-05-25 Thread Meta via Digitalmars-d-learn

On Monday, 25 May 2015 at 15:46:54 UTC, Dennis Ritchie wrote:

On Monday, 25 May 2015 at 15:06:45 UTC, Alex Parrill wrote:
Hint: Use `cartesianProduct` [1] with three iota ranges to 
replace the foreachs, and `filter` to replace the if


[1] 
http://dlang.org/phobos/std_algorithm_setops.html#.cartesianProduct


Thank you. Is it possible to replace the loop `foreach` 
function `each` or `chunkBy` with the auxiliary functions?


import std.stdio, std.algorithm, std.range;

void main() {

const x = 12, y = 65, z = 50, s = 1435;

auto a = iota(0, x + 1);

foreach (idx; cartesianProduct(a, a, a).filter!(i = i[0] * 
(y + 3 * z) + i[1] * (y + 2 * z) + i[2] * (y + z) == s)) {

writeln(idx[0] + idx[1] + idx[2]);
writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
writeln(idx[0], idx[1], idx[2]);
}
}
-
http://rextester.com/HZP96719


import std.algorithm;
import std.range;
import std.stdio;

void main()
{
const x = 12, y = 65, z = 50, s = 1435;
auto a = iota(0, x + 1);
cartesianProduct(a, a, a)
.filter!(i = i[0] * (y + 3 * z)
+ i[1] * (y + 2 * z)
+ i[2] * (y + z)
== s)
.each!((idx)
{
writeln(idx[0] + idx[1] + idx[2]);
writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
writeln(idx[0], idx[1], idx[2]);
});
}


Replacing nested loops foreach using map/each/etc

2015-05-25 Thread Dennis Ritchie via Digitalmars-d-learn

Hi,
Is it possible to write such a construction that could push 
immediately to a conditional statement without using nested 
loops? Ie organize search directly in the iterator if provided by 
a map / each / iota and other support functions.

Ie I want to write this code shorter :)

import std.stdio;

void main() {

const x = 12, y = 65, z = 50, s = 1435;

foreach (i; 0 .. x + 1)
foreach (j; 0 .. x + 1)
foreach (k; 0 .. x + 1)
if (i * (y + 3 * z) + j * (y + 2 * z) + k * (y + 
z) == s) {

writeln(i + j + k);
writeln(i * 3 + j * 2 + k);
writeln(i * 3 + j * 2 + k);
writeln(i, j, k);
}
}
-
http://rextester.com/SJTU87854


Re: Replacing nested loops foreach using map/each/etc

2015-05-25 Thread Dennis Ritchie via Digitalmars-d-learn

On Monday, 25 May 2015 at 15:06:45 UTC, Alex Parrill wrote:
Hint: Use `cartesianProduct` [1] with three iota ranges to 
replace the foreachs, and `filter` to replace the if


[1] 
http://dlang.org/phobos/std_algorithm_setops.html#.cartesianProduct


Thank you. Is it possible to replace the loop `foreach` function 
`each` or `chunkBy` with the auxiliary functions?


import std.stdio, std.algorithm, std.range;

void main() {

const x = 12, y = 65, z = 50, s = 1435;

auto a = iota(0, x + 1);

foreach (idx; cartesianProduct(a, a, a).filter!(i = i[0] * 
(y + 3 * z) + i[1] * (y + 2 * z) + i[2] * (y + z) == s)) {

writeln(idx[0] + idx[1] + idx[2]);
writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
writeln(idx[0], idx[1], idx[2]);
}
}
-
http://rextester.com/HZP96719


Re: Replacing nested loops foreach using map/each/etc

2015-05-25 Thread Alex Parrill via Digitalmars-d-learn

On Monday, 25 May 2015 at 14:25:52 UTC, Dennis Ritchie wrote:

Hi,
Is it possible to write such a construction that could push 
immediately to a conditional statement without using nested 
loops? Ie organize search directly in the iterator if provided 
by a map / each / iota and other support functions.

Ie I want to write this code shorter :)

import std.stdio;

void main() {

const x = 12, y = 65, z = 50, s = 1435;

foreach (i; 0 .. x + 1)
foreach (j; 0 .. x + 1)
foreach (k; 0 .. x + 1)
if (i * (y + 3 * z) + j * (y + 2 * z) + k * (y 
+ z) == s) {

writeln(i + j + k);
writeln(i * 3 + j * 2 + k);
writeln(i * 3 + j * 2 + k);
writeln(i, j, k);
}
}
-
http://rextester.com/SJTU87854


Hint: Use `cartesianProduct` [1] with three iota ranges to 
replace the foreachs, and `filter` to replace the if


[1] 
http://dlang.org/phobos/std_algorithm_setops.html#.cartesianProduct


Re: Replacing nested loops foreach using map/each/etc

2015-05-25 Thread Dennis Ritchie via Digitalmars-d-learn

On Monday, 25 May 2015 at 16:41:35 UTC, Meta wrote:

import std.algorithm;
import std.range;
import std.stdio;

void main()
{
const x = 12, y = 65, z = 50, s = 1435;
auto a = iota(0, x + 1);
cartesianProduct(a, a, a)
.filter!(i = i[0] * (y + 3 * z)
+ i[1] * (y + 2 * z)
+ i[2] * (y + z)
== s)
.each!((idx)
  {
  writeln(idx[0] + idx[1] + idx[2]);
  writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
  writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
  writeln(idx[0], idx[1], idx[2]);
  });
}


Thanks. I do not even know what `each` support braces.


Re: How to append range to array?

2015-05-25 Thread John Colvin via Digitalmars-d-learn
On Saturday, 23 May 2015 at 07:03:35 UTC, Vladimir Panteleev 
wrote:

int[] arr = [1, 2, 3];
auto r = iota(4, 10);
// ???
assert(equal(arr, iota(1, 10)));

Hopefully in one GC allocation (assuming we know the range's 
length).


I tried std.range.primitives.put but its behavior seems a 
little mysterious:


This compiles but asserts at runtime:

int[] arr = [1, 2, 3];
arr.put(iota(4, 10));

And this is even weirder, can you guess what it will print?

int[] arr = [1, 2, 3];
arr.put(4);
writeln(arr);


int[] arr = [1,2,3];
auto r = iota(4, 10);
auto app = arr.refAppender;
app.put(r);
assert(equal(arr, iota(1, 10)));

which of course you wrap with something like

auto append(T, R)(ref T arr, R r)
if(is(T : Q[], Q)  isInputRange!r);
{
auto app = arr.refAppender;
app.put(r);
return arr;
}

to get

int[] arr = [1,2,3];
auto r = iota(4, 10);
arr.append(r);
assert(equal(arr, iota(1, 10)));

Walter has mentioned that he was interested in adding more 
range-awareness to the language, so who knows, maybe this sort of 
thing will get sugar at some point.


Re: Replacing nested loops foreach using map/each/etc

2015-05-25 Thread Meta via Digitalmars-d-learn

On Monday, 25 May 2015 at 17:05:35 UTC, Dennis Ritchie wrote:

On Monday, 25 May 2015 at 16:41:35 UTC, Meta wrote:

import std.algorithm;
import std.range;
import std.stdio;

void main()
{
   const x = 12, y = 65, z = 50, s = 1435;
   auto a = iota(0, x + 1);
   cartesianProduct(a, a, a)
.filter!(i = i[0] * (y + 3 * z)
   + i[1] * (y + 2 * z)
   + i[2] * (y + z)
   == s)
.each!((idx)
 {
 writeln(idx[0] + idx[1] + idx[2]);
 writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
 writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
 writeln(idx[0], idx[1], idx[2]);
 });
}


Thanks. I do not even know what `each` support braces.


`each` doesn't support braces. There are 4 ways to write a 
function/delegate literal in D (with a few minor variations):


Short form:
function(int i) = i;
(int i) = i
(i) = i
i = i

Long form:
function(int i) { return i; }
(int i) { return i; }
(i) { return i; }
{ return 0; }

http://dlang.org/expression.html#FunctionLiteral
function


Re: Replacing nested loops foreach using map/each/etc

2015-05-25 Thread Dennis Ritchie via Digitalmars-d-learn

On Monday, 25 May 2015 at 19:16:04 UTC, anonymous wrote:

On Monday, 25 May 2015 at 17:52:09 UTC, Dennis Ritchie wrote:

But why is the solution breaks down when `s = 1` ? :)

import std.stdio, std.algorithm, std.range;

int c;
const x = 12, y = 65, z = 50, s = 10;


Which is it, now? 4 or 5 zeros?


No difference!


void solve(Range)(Range r) {
	cartesianProduct(r, r, r).filter!(i = i[0] * (y + 3 * z) + 
i[1] * (y + 2 * z) + i[2] * (y + z) == s).each!dout;

}

void main() {

   auto a = iota(0, x + 1).array;

   solve(a);

   writefln(`%s total`, c);
}

void dout(Tuple)(Tuple idx) {
   ++c;
}
-
http://rextester.com/XGDL26042


What do you mean it breaks down? Your original code doesn't 
print anything for s = 10_000 or s = 100_000, either.


Excuse me, this is my blemish! I forgot that the constant `x` 
depends on `s`. Everything works correctly:


import std.stdio, std.algorithm, std.range;

void solve(Range)(Range r) {
cartesianProduct(r, r, r).filter!(i = i[0] * (y + 3 * z) + 
i[1] * (y + 2 * z) + i[2] * (y + z) == s).each!dout;

}

const y = 65, z = 50, s = 10;
const x = s / (y + z);

void main() {

auto a = iota(0, x + 1);

solve(a);
}

auto dout(Tuple)(Tuple idx) {
writefln(`%s apples`, idx[0] + idx[1] + idx[2]);
writefln(`%s gingerbread`, idx[0] * 3 + idx[1] * 2 + idx[2]);
writefln(`%s pharynx tea`, idx[0] * 3 + idx[1] * 2 + idx[2]);
writefln(Sour: %s; semi-acid: %s; sweet: %s.\n, idx[0], 
idx[1], idx[2]);

}
-
http://rextester.com/MMCI9993


Re: Replacing nested loops foreach using map/each/etc

2015-05-25 Thread anonymous via Digitalmars-d-learn

On Monday, 25 May 2015 at 17:52:09 UTC, Dennis Ritchie wrote:

But why is the solution breaks down when `s = 1` ? :)

import std.stdio, std.algorithm, std.range;

int c;
const x = 12, y = 65, z = 50, s = 10;


Which is it, now? 4 or 5 zeros?


void solve(Range)(Range r) {
	cartesianProduct(r, r, r).filter!(i = i[0] * (y + 3 * z) + 
i[1] * (y + 2 * z) + i[2] * (y + z) == s).each!dout;

}

void main() {

auto a = iota(0, x + 1).array;

solve(a);

writefln(`%s total`, c);
}

void dout(Tuple)(Tuple idx) {
++c;
}
-
http://rextester.com/XGDL26042


What do you mean it breaks down? Your original code doesn't 
print anything for s = 10_000 or s = 100_000, either.


Re: Replacing nested loops foreach using map/each/etc

2015-05-25 Thread Dennis Ritchie via Digitalmars-d-learn

On Monday, 25 May 2015 at 17:19:27 UTC, Meta wrote:
`each` doesn't support braces. There are 4 ways to write a 
function/delegate literal in D (with a few minor variations):


Short form:
function(int i) = i;
(int i) = i
(i) = i
i = i

Long form:
function(int i) { return i; }
(int i) { return i; }
(i) { return i; }
{ return 0; }

http://dlang.org/expression.html#FunctionLiteral
function


Thanks.

But why is the solution breaks down when `s = 1` ? :)

import std.stdio, std.algorithm, std.range;

int c;
const x = 12, y = 65, z = 50, s = 10;

void solve(Range)(Range r) {
	cartesianProduct(r, r, r).filter!(i = i[0] * (y + 3 * z) + i[1] 
* (y + 2 * z) + i[2] * (y + z) == s).each!dout;

}

void main() {

auto a = iota(0, x + 1).array;

solve(a);

writefln(`%s total`, c);
}

void dout(Tuple)(Tuple idx) {
++c;
}
-
http://rextester.com/XGDL26042


Re: deserialization: creating a class instance without calling constructor

2015-05-25 Thread timotheecour via Digitalmars-d-learn

On Thursday, 21 May 2015 at 19:06:35 UTC, Jacob Carlborg wrote:
On 2015-05-21 11:06, Timothee Cour via Digitalmars-d-learn 
wrote:
Can I create an instance of A without calling a constructor? 
(see below)
Use case: for generic deserialiaztion, when the 
deserialization library
encounters a class without default constructor for example (it 
knows
what the fields should be set to, but doesn't know how to 
construct the

object).

class A{
  int x=2;
  this(int x){
this.x=x;
  }
}


This came up here:
https://github.com/msgpack/msgpack-d/issues/54#issuecomment-104136148
I provide some hacky solution for that in that thread but I 
suspect it's

not safe and something is missing.


Here's how I do it in my serialization library Orange [1]

[1] 
https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d#L166


Thanks!


Re: Idiomatic way to call base method in generic code

2015-05-25 Thread ketmar via Digitalmars-d-learn
On Mon, 25 May 2015 09:24:56 +, ZombineDev wrote:

 alias can't refer to a nested member:
 -
 struct Point2 {
  float x;
  float y;
 }
 
 struct Line2 {
  Point2 start;
  Point2 end;
 
  mixin Access;
 
  // alias x1 = this.start.x; - this doesn't work :(
 
  alias x1 = get!start.x;
  alias y1 = get!start.y;
  alias x2 = get!end.x;
  alias y2 = get!end.y;
 }
 
 // I need to use a mixin to flatten the access :(
 private mixin template Access()
 {
  ref auto get(string accessPattern)() inout {
  return mixin(accessPattern);
  }
 }
 -

i wonder if there is a reason for that limitation (except nobody 
implemented that feature yet, of course).

signature.asc
Description: PGP signature


Re: Idiomatic way to call base method in generic code

2015-05-25 Thread ketmar via Digitalmars-d-learn
On Mon, 25 May 2015 09:24:56 +, ZombineDev wrote:

 On Monday, 25 May 2015 at 07:57:49 UTC, ketmar wrote:
 i don't know why you want that, but something like this may do:

 auto callBaseMethod(string MTN, C, Args...) (inout C self, Args args) {
   alias FSC = BaseClassesTuple!(C)[0];
   return mixin(`self.`~FSC.stringof~`.`~MTN~(args));
 }

 writeln(d.callBaseMethod!toString);


 Thanks!

note that this funny trick works even for `void` methods, due to magic of 
`auto` return type.

signature.asc
Description: PGP signature


Re: Lazy variadic not working, any alternatives?

2015-05-25 Thread Tofu Ninja via Digitalmars-d-learn

On Tuesday, 26 May 2015 at 05:22:26 UTC, Tofu Ninja wrote:
Actually the code seems to compile on 2.067.1 but definitely does 
not work as expected.


Another example of Lazy variadic to show how it works...

void main(string[] args)
{
test(a(), b(), c());
}

bool a()
{
writeln(a);
return true;
}

bool b()
{
writeln(b);
return true;
}

bool c()
{
writeln(c);
return true;
}

void test(lazy bool[] c...)
{
for(int i = 0; i  c.length; i++)
{
writeln(iteration: , i);
if(c[i]) writeln(success);
}
}

prints...

a
b
c
iteration: 0
a
b
c
success
a
b
c
iteration: 1
a
b
c
success
a
b
c
iteration: 2
a
b
c
success
a
b
c

Though because it still runs in order, maybe I can still make 
this work...


Re: Lazy variadic not working, any alternatives?

2015-05-25 Thread Tofu Ninja via Digitalmars-d-learn

On Tuesday, 26 May 2015 at 05:43:59 UTC, Tofu Ninja wrote:

On Tuesday, 26 May 2015 at 05:22:26 UTC, Tofu Ninja wrote:
Actually the code seems to compile on 2.067.1 but definitely 
does not work as expected.

...


I guess it stems from the fact that its lazy (bool[])
Wish I could do (lazy bool)[]


Re: Lazy variadic not working, any alternatives?

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

On Tuesday, 26 May 2015 at 05:22:26 UTC, Tofu Ninja wrote:
So I was writing a simple parser and I wanted a functionality 
that was basically try list of tokens in order and if any of 
them fail, rewind input.


I tried using a lazy variadic function:

bool tok_and(lazy bool[] terms ...)
{
auto backup = getInputLocation();
for(int i = 0; i  terms.length; i++)
{
if(terms[i] == false)
{
rewind(backup);
return false;
}
}
return true;
}

But this does not work because of BUG9110
https://issues.dlang.org/show_bug.cgi?id=9110

Any one have an idea how to achieve similar functionality 
without a bunch of boilerplate at the call site? The lazy 
version would have been nice because it would have allowed for:


if(tok_and(ident(), equal(), expression())) {...}
else if(tok_and(some(), other(), grammar())) {...}
else ...


Something like this appears to work:

import std.typetuple : allSatisfy;

enum implicityConvertibleToBool(T) = is(T : bool);

bool tok_and(Args...)(lazy Args terms)
if(allSatisfy!(implicitlyConvertibleToBool, Args))
{
auto backup = getInputLocation();
foreach(term; terms)
{
if(term == false)
{
rewind(backup);
return false;
}
}
return true;
}


Lazy variadic not working, any alternatives?

2015-05-25 Thread Tofu Ninja via Digitalmars-d-learn
So I was writing a simple parser and I wanted a functionality 
that was basically try list of tokens in order and if any of 
them fail, rewind input.


I tried using a lazy variadic function:

bool tok_and(lazy bool[] terms ...)
{
auto backup = getInputLocation();
for(int i = 0; i  terms.length; i++)
{
if(terms[i] == false)
{
rewind(backup);
return false;
}
}
return true;
}

But this does not work because of BUG9110
https://issues.dlang.org/show_bug.cgi?id=9110

Any one have an idea how to achieve similar functionality without 
a bunch of boilerplate at the call site? The lazy version would 
have been nice because it would have allowed for:


if(tok_and(ident(), equal(), expression())) {...}
else if(tok_and(some(), other(), grammar())) {...}
else ...