Re: Avoid GC with closures
On Sunday, 29 May 2016 at 11:16:57 UTC, Dicebot wrote: On 05/28/2016 09:58 PM, Iakh wrote: Yeah. It doesn't capture any context. But once it does it would be an error. Custom allocators are not very suitable for things like closures because of undefined lifetime. Even if it was allowed to replace allocator, you would be limited to either GC or RC based one anyway to keep things @safe. Yes. It's better to pass something like memory management strategy instead of just allocator like rc ptr or uniquePtr
Re: Avoid GC with closures
On Sunday, 29 May 2016 at 11:16:57 UTC, Dicebot wrote: On 05/28/2016 09:58 PM, Iakh wrote: Yeah. It doesn't capture any context. But once it does it would be an error. Custom allocators are not very suitable for things like closures because of undefined lifetime. Even if it was allowed to replace allocator, you would be limited to either GC or RC based one anyway to keep things @safe. Maybe an interface for a ref counting allocator (that leverages Andrei's idea to use AffixAllocator's interface for storing RC metadata) can be used, provided that the interface is in druntime and the compiler knows how to use it. BTW, AffixAllocator's interface abstracts whether the metadata is stored next to the allocation or in a separate area, but the current design needs to be fixed w.r.t to shared-ness, because it breaks the type system: http://forum.dlang.org/post/bscksxwxuvzefymbi...@forum.dlang.org
Re: Avoid GC with closures
On 05/28/2016 09:58 PM, Iakh wrote: > Yeah. It doesn't capture any context. But once it does it > would be an error. Custom allocators are not very suitable for things like closures because of undefined lifetime. Even if it was allowed to replace allocator, you would be limited to either GC or RC based one anyway to keep things @safe.
Re: Avoid GC with closures
On Thursday, 26 May 2016 at 21:10:30 UTC, bpr wrote: On Thursday, 26 May 2016 at 18:53:35 UTC, Iakh wrote: Functions with lambdas cannot be @nogc as far as they allocates closures. Counterexample: // Note that this is NOT a good way to do numerical quadrature! double integrate(scope double delegate(double x) @nogc f, double lo, double hi, size_t n) @nogc { double result = 0.0; double dx = (hi - lo) / n; double dx2 = dx * 0.5; for (size_t i = 1; i <= n; i++) { result += f(lo + i * dx2) * dx; } return result; } double integrate(scope double delegate(double, double) @nogc f, double x0, double x1, double y0, double y1, size_t nX, size_t nY) @nogc { return integrate((y) => integrate((x) => f(x,y), x0, x1, nX), y0, y1, nY); } Functions with @nogc downward funarg lambdas (delegates) can be @nogc. Didn't know about "scope". It solves problem partially. I can't parse the rest of your post, maybe I misunderstand you. The problem is that delegates allocates with GC. And proposed solution it to tell to the compiler what to use instead of GC heap. It is not only about scoped. It is mostly about memory allocated for closure.
Re: Avoid GC with closures
On Friday, 27 May 2016 at 10:34:38 UTC, Kagamin wrote: On Thursday, 26 May 2016 at 18:53:35 UTC, Iakh wrote: void g() @nogc { catch scope(void); int[N] arr = [/*...*/]; arr[].sort!((a, b) => a > b); } This compiles just fine and doesn't allocate: void g() @nogc { int[2] arr = [5,4]; arr[].sort!((a, b) => a > b); } Yeah. It doesn't capture any context. But once it does it would be an error.
Re: Avoid GC with closures
On Thursday, 26 May 2016 at 18:53:35 UTC, Iakh wrote: void g() @nogc { catch scope(void); int[N] arr = [/*...*/]; arr[].sort!((a, b) => a > b); } This compiles just fine and doesn't allocate: void g() @nogc { int[2] arr = [5,4]; arr[].sort!((a, b) => a > b); }
Re: Avoid GC with closures
On Thursday, 26 May 2016 at 18:53:35 UTC, Iakh wrote: Functions with lambdas cannot be @nogc as far as they allocates closures. Counterexample: // Note that this is NOT a good way to do numerical quadrature! double integrate(scope double delegate(double x) @nogc f, double lo, double hi, size_t n) @nogc { double result = 0.0; double dx = (hi - lo) / n; double dx2 = dx * 0.5; for (size_t i = 1; i <= n; i++) { result += f(lo + i * dx2) * dx; } return result; } double integrate(scope double delegate(double, double) @nogc f, double x0, double x1, double y0, double y1, size_t nX, size_t nY) @nogc { return integrate((y) => integrate((x) => f(x,y), x0, x1, nX), y0, y1, nY); } Functions with @nogc downward funarg lambdas (delegates) can be @nogc. I can't parse the rest of your post, maybe I misunderstand you.
Avoid GC with closures
Functions with lambdas cannot be @nogc as far as they allocates closures. And the way lambdas works is completely different from C++ way. In D using lambda we define how some part of "stack" frame allocates. So in some aspect closure allocation is property of a function. So we need a way to tell compiler how to handle this part of frame. For exapmle: void g() @nogc { catch scope(void); int[N] arr = [/*...*/]; arr[].sort!((a, b) => a > b); } Where "catch scope(void);" sets allocator for all lambdas. If it is void closure will be allocated on the stack. Once we will have allocators we will be able to pass them as closure handlers.