digitalmars.D.learn - delegate issue
- captaindet (16/16) Jun 01 2014 hi,
- MrSmith (8/29) Jun 02 2014 You can't assign a delegate at compile time now.
- captaindet (5/39) Jun 02 2014 i knew about the static constructor, mentioned it in my OP ;)
- Steven Schveighoffer (32/78) Jun 02 2014 FYI, the module ctor/dtor cycles thing is an interesting problem. When D...
- captaindet (3/81) Jun 02 2014 thanks a lot, steve! turned out - not surprisingly - that i would run in...
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (6/27) Jun 02 2014 This doesn't work, because a delegate needs a context it can
- captaindet (4/35) Jun 02 2014 so the real explanation is that a module as such has no context. much of...
- Timon Gehr (3/12) Jun 02 2014 The real explanation is that this doesn't work just because it doesn't
- captaindet (3/34) Jun 02 2014 i knew about the static constructor workaround (mentioned it in my OP). ...
- captaindet (12/45) Jun 02 2014 FWIW, tried toDelegate() and it does not work either:
hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a "feature" that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. ---- module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){}
Jun 01 2014
On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote:hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a "feature" that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. ---- module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){}You can't assign a delegate at compile time now. But you can do this in static constructor like this: int delegate(int) dg; static this() { dg = delegate int(int){ return 666; }; }
Jun 02 2014
On 2014-06-02 08:03, MrSmith wrote:On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote:i knew about the static constructor, mentioned it in my OP ;) tried it in my project proper and got run-time cycle detected between modules ctors/dtors :( something new to figure out now. thanks, dethi, i stumbled upon something weird - it looks like a bug to me but maybe it is a "feature" that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. ---- module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){}You can't assign a delegate at compile time now. But you can do this in static constructor like this: int delegate(int) dg; static this() { dg = delegate int(int){ return 666; }; }
Jun 02 2014
On Mon, 02 Jun 2014 10:37:07 -0400, captaindet <2krnk gmx.net> wrote:On 2014-06-02 08:03, MrSmith wrote:FYI, the module ctor/dtor cycles thing is an interesting problem. When D decides to call module ctors or dtors, it wants to initialize them in an order where two initializations don't depend on one another. For instance: module a; import b; int x; static this() { x = b.x;} module b; import a; int x; static this() { x = a.x;} But of course, D does not know what exactly is done in module a, and module b. It could be: module a; import b; int x; static this() { x = b.x; } module b; import a; int x; static this() { x = 15;} Which could be perfectly legal, as long as module b is initialized before module a. But D doesn't have the information to sort this out. So at the moment, it has to assume the first situation, and reject the code. And it can only detect this at runtime, since we have no way to tell the linker to refuse to link this code. The typical solution is to put your static ctors into another module, which nothing will import (and therefore cannot be part of a cycle). A module with no static ctors/dtors will not be flagged as causing a problem. -SteveOn Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote:i knew about the static constructor, mentioned it in my OP ;) tried it in my project proper and got run-time cycle detected between modules ctors/dtors :( something new to figure out now.hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a "feature" that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. ---- module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){}You can't assign a delegate at compile time now. But you can do this in static constructor like this: int delegate(int) dg; static this() { dg = delegate int(int){ return 666; }; }
Jun 02 2014
On 2014-06-02 09:57, Steven Schveighoffer wrote:On Mon, 02 Jun 2014 10:37:07 -0400, captaindet <2krnk gmx.net> wrote:thanks a lot, steve! turned out - not surprisingly - that i would run into the ctor/dtor cycle issue whenever the user code module had a static constructor (even if not due to the delegate workaround mixin). i was able to refactor my package and after 'outsourcing' of the static constructor there, i can now use the mixed in static constructors in the user module to initialize the delegate with a default. not pretty, but it works! /detOn 2014-06-02 08:03, MrSmith wrote:FYI, the module ctor/dtor cycles thing is an interesting problem. When D decides to call module ctors or dtors, it wants to initialize them in an order where two initializations don't depend on one another. For instance: module a; import b; int x; static this() { x = b.x;} module b; import a; int x; static this() { x = a.x;} But of course, D does not know what exactly is done in module a, and module b. It could be: module a; import b; int x; static this() { x = b.x; } module b; import a; int x; static this() { x = 15;} Which could be perfectly legal, as long as module b is initialized before module a. But D doesn't have the information to sort this out. So at the moment, it has to assume the first situation, and reject the code. And it can only detect this at runtime, since we have no way to tell the linker to refuse to link this code. The typical solution is to put your static ctors into another module, which nothing will import (and therefore cannot be part of a cycle). A module with no static ctors/dtors will not be flagged as causing a problem. -SteveOn Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote:i knew about the static constructor, mentioned it in my OP ;) tried it in my project proper and got run-time cycle detected between modules ctors/dtors :( something new to figure out now.hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a "feature" that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. ---- module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){}You can't assign a delegate at compile time now. But you can do this in static constructor like this: int delegate(int) dg; static this() { dg = delegate int(int){ return 666; }; }
Jun 02 2014
On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote:hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a "feature" that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. ---- module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){}This doesn't work, because a delegate needs a context it can capture, which is available only inside of a function. The workaround is either, as Mr Smith suggests, to use a static constructor, or you can use std.functional.toDelegate() (probably, didn't test).
Jun 02 2014
On 2014-06-02 08:08, "Marc Schütz" <schuetzm gmx.net>" wrote:On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote:so the real explanation is that a module as such has no context. much of the module design has the look and feel as if it were some sort of object, so this is a bit of a surprise to me. well, i learned something. thanks, dethi, i stumbled upon something weird - it looks like a bug to me but maybe it is a "feature" that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. ---- module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){}This doesn't work, because a delegate needs a context it can capture, which is available only inside of a function.
Jun 02 2014
On 06/02/2014 04:30 PM, captaindet wrote:The real explanation is that this doesn't work just because it doesn't work and it might/should work at some point in the future.so the real explanation is that a module as such has no context. much of the module design has the look and feel as if it were some sort of object, so this is a bit of a surprise to me. well, i learned something. thanks, detThis doesn't work, because a delegate needs a context it can capture, which is available only inside of a function.
Jun 02 2014
On 2014-06-02 08:08, "Marc Schütz" <schuetzm gmx.net>" wrote:On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote:i knew about the static constructor workaround (mentioned it in my OP). works in a simple case, but when i tried it in my project proper i hit a run-time error: cycle detected between modules ctors/dtors :( could be an unrelated, so far undetected bug, will look into it tonight. will try std.functional.toDelegate() as well, maybe it will do the trick. thanks, dethi, i stumbled upon something weird - it looks like a bug to me but maybe it is a "feature" that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. ---- module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){}This doesn't work, because a delegate needs a context it can capture, which is available only inside of a function. The workaround is either, as Mr Smith suggests, to use a static constructor, or you can use std.functional.toDelegate() (probably, didn't test).
Jun 02 2014
On 2014-06-02 08:08, "Marc Schütz" <schuetzm gmx.net>" wrote:On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote:FWIW, tried toDelegate() and it does not work either: -------- module demo2; import std.functional : toDelegate; int function(int) fn = function int(int){ return 42; }; // ok int dg_def(int){ return 666; } int delegate(int) dg = toDelegate(&dg_def); // c:\D\DMD2\windows\bin\..\..\src\phobos\std\functional.d(758): Error: Cannot convert &int delegate(int a0) system to void* at compile time // demo2.d(8): called from here: toDelegate(& dg_def) void main(){}hi, i stumbled upon something weird - it looks like a bug to me but maybe it is a "feature" that is unclear to me. so i know i can declare function and delegate pointers at module level. for function pointers, i can initialize with a lambda. BUT for delegates i get an error - see below i found out that using module static this(){...} provides a workaround, but why is this necessary? also, if there is a good reason after all then the error message should make more sense. /det ps: i know there is a shorthand syntax for this. ---- module demo; int function(int) fn = function int(int){ return 42; }; // ok int delegate(int) dg = delegate int(int){ return 666; }; // demo.d(6): Error: non-constant nested delegate literal expression __dgliteral6 void main(){}This doesn't work, because a delegate needs a context it can capture, which is available only inside of a function. The workaround is either, as Mr Smith suggests, to use a static constructor, or you can use std.functional.toDelegate() (probably, didn't test).
Jun 02 2014