digitalmars.D.learn - Lazy variadic not working, any alternatives?
- Tofu Ninja (25/25) May 25 2015 So I was writing a simple parser and I wanted a functionality
- Tofu Ninja (61/61) May 25 2015 On Tuesday, 26 May 2015 at 05:22:26 UTC, Tofu Ninja wrote:
- Tofu Ninja (3/7) May 25 2015 I guess it stems from the fact that its "lazy (bool[])"
- Steven Schveighoffer (6/13) May 26 2015 Lazy variadic functions are clearly defined here:
- John Colvin (18/43) May 25 2015 Something like this appears to work:
- Tofu Ninja (3/20) May 25 2015 Hmmm.... this does seem to work. Does this essentially expand out
- John Colvin (9/32) May 26 2015 Apparently yes, which surprised me. Storage classes and
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 ...
May 25 2015
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...
May 25 2015
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)[]"
May 25 2015
On 5/25/15 11:53 PM, Tofu Ninja wrote:On Tuesday, 26 May 2015 at 05:43:59 UTC, Tofu Ninja wrote:Lazy variadic functions are clearly defined here: http://dlang.org/function.html The correct way to do it is: bool tok_and(bool delegate()[] terms ...) -SteveOn 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)[]"
May 26 2015
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;
}
May 25 2015
On Tuesday, 26 May 2015 at 05:54:11 UTC, John Colvin wrote:
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;
}
Hmmm.... this does seem to work. Does this essentially expand out
to tok_and(lazy bool arg1, lazy bool arg2, ...)?
May 25 2015
On Tuesday, 26 May 2015 at 06:04:59 UTC, Tofu Ninja wrote:On Tuesday, 26 May 2015 at 05:54:11 UTC, John Colvin wrote:Apparently yes, which surprised me. Storage classes and TypeTuples (or Arguments, as they are now) are a bit of a dark corner. E.g. void foo(ref int, ref int); alias A(T...) = T; static assert(is(ParameterTypeTuple!foo == A!(ParameterTypeTuple!foo))); That fails.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; }Hmmm.... this does seem to work. Does this essentially expand out to tok_and(lazy bool arg1, lazy bool arg2, ...)?
May 26 2015









Steven Schveighoffer <schveiguy yahoo.com> 