www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Lazy evaluation and nogc code

reply Nick Vitsas <vineek email.com> writes:
Hello,

I've been playing around with the idea of lazy evaluation for 
function arguments [1] and I really like how it can be used to 
simplify deep nested loops operating on structured data.

It also seems that you can get quite far without invoking the GC 
using the `scope` keyword. I’ve been experimenting on some code 
and I’ve reached an interesting situation. A similar thing has 
been filed as a bug [2] but it seems that `scope` was not 
available in its current form back then.

Here’s some code to present the case.

 nogc lazy evaluation using scoped delegates:

Compiles fine in DMD v2.074.0,

import std.stdio;
int DoTimes(int count, scope int delegate()  nogc nothrow Dg) 
 nogc nothrow {
     foreach (i ; 0 .. count)
         Dg();

     return 1;
}

int DoAgain()  nogc nothrow {
     int x = 0, y = 10;
     return DoTimes(2, { return DoTimes(4, { return printf("x:%d, 
y:%d\n", x++, y++); }); } );
}

void foo()  nogc nothrow {
     DoTimes(2, { return DoTimes(4, { return DoAgain(); }); } );
}

void main(string[] args) {
   auto Lambda = () => foo();
   Lambda();
}

 nogc lazy evaluation using `lazy` arguments:

Exits with
Error:  nogc function 'app.DoTimes' cannot call non- nogc 
delegate 'Dg' in DMD v2.074.0.

import std.stdio;
int DoTimes(int count, scope lazy int Dg)  nogc nothrow
{
     foreach (i ; 0 .. count)
         Dg();

     return 1;
}

int DoAgain()  nogc nothrow {
     int x = 0, y = 10;
     return DoTimes(2, DoTimes(4, printf("x:%d, y:%d\n", x++, y++) 
) );
}

void foo()  nogc nothrow {
     DoTimes(2, DoTimes(4, DoAgain() ) );
}

void main(string[] args) {

   auto Lambda = () => foo();
   Lambda();

}

typeof(Dg) returns `int` and not some kind of delegate. It seems 
that the conversion happens at a later stage and so we do not get 
the expected type.

In any case, do you think that `scope` should allow for such code 
to compile? Since you can get the desired result using the 
verbose version, I think you should also be able to using the 
`lazy` construct.

Thank you for any suggestions.

[1] https://dlang.org/lazy-evaluation.html
[2] https://issues.dlang.org/show_bug.cgi?id=12664
Jun 03 2017
parent Basile B. <b2.temp gmx.com> writes:
On Saturday, 3 June 2017 at 14:34:41 UTC, Nick Vitsas wrote:
 In any case, do you think that `scope` should allow for such 
 code to compile? Since you can get the desired result using the 
 verbose version, I think you should also be able to using the 
 `lazy` construct.
I think so. There's even a pull request that modifies lazy so that other functions attributes (incl. nogc) are inferred. https://github.com/dlang/dmd/pull/6348 The problem is that it seems to be out of scope / interest now (last activity was on 24 of Feb), almost 6 months.
Jun 03 2017