Thread overview | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 06, 2011 [Issue 5710] New: cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
http://d.puremagic.com/issues/show_bug.cgi?id=5710 Summary: cannot use delegates as parameters to non-global template Product: D Version: D2 Platform: Other OS/Version: Windows Status: NEW Keywords: rejects-valid Severity: normal Priority: P2 Component: DMD AssignedTo: nobody@puremagic.com ReportedBy: dsimcha@yahoo.com --- Comment #0 from David Simcha <dsimcha@yahoo.com> 2011-03-06 06:26:40 PST --- This pretty severely impacts the usability of template alias parameters for lambda functions. class Foo { uint doStuff(alias fun)(uint a, uint b) { return fun(a, b); } } void main() { auto foo = new Foo; uint add(uint a, uint b) { return a + b; } foo.doStuff!add(1, 2); } test9.d(10): Error: template instance cannot use local 'add' as parameter to non-global template doStuff(alias fun) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 06, 2011 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 Walter Bright <bugzilla@digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bugzilla@digitalmars.com --- Comment #1 from Walter Bright <bugzilla@digitalmars.com> 2011-03-06 10:16:43 PST --- The reason this does not work is because the instantiation of the doStuff() function would require *two* context pointers: 1. a 'this' pointer to the object Foo 2. a 'this' pointer to the stack frame of main() and there can be only one. It will work if you declare add() as being static, because then you're saying that it does not need a context pointer to main(). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 06, 2011 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 --- Comment #2 from David Simcha <dsimcha@yahoo.com> 2011-03-06 11:05:37 PST --- So is this an WONTFIX, then? Unfortunately it severely hurts my std.parallelism design in some use cases, and a workaround for it would be a significant PITA to implement, make the API uglier, and possibly be inefficient. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 06, 2011 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 --- Comment #3 from Walter Bright <bugzilla@digitalmars.com> 2011-03-06 15:19:12 PST --- (In reply to comment #2) > So is this an WONTFIX, then? Unless there's an epiphany somewhere, yes. How would you suggest two hidden context pointers be handled? Is it clear that two context pointers are required (at least for this example)? > Unfortunately it severely hurts my > std.parallelism design in some use cases, and a workaround for it would be a > significant PITA to implement, make the API uglier, and possibly be > inefficient. I don't know enough about your design to offer help with that. Perhaps instead of an alias parameter, make fun explicitly a delegate? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 06, 2011 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 Andrei Alexandrescu <andrei@metalanguage.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |andrei@metalanguage.com --- Comment #4 from Andrei Alexandrescu <andrei@metalanguage.com> 2011-03-06 15:31:45 PST --- (In reply to comment #3) > (In reply to comment #2) > > So is this an WONTFIX, then? > > Unless there's an epiphany somewhere, yes. How would you suggest two hidden context pointers be handled? Is it clear that two context pointers are required (at least for this example)? > > > Unfortunately it severely hurts my > > std.parallelism design in some use cases, and a workaround for it would be a > > significant PITA to implement, make the API uglier, and possibly be > > inefficient. > > I don't know enough about your design to offer help with that. Perhaps instead of an alias parameter, make fun explicitly a delegate? There are several things here. First, the compiler should figure out that add does not need a frame pointer and consider it a static inner function, not a delegate. Second, we need to agree that the reason you invoke is tied to the implementation - you use the same pointer for the class and for the hidden frame pointer, whereas of course there's no imposition to do so. The hidden "this" parameter could go pretty much anywhere else. One way or another we must fix this. Oddly, a number of similar uses do work "by mistake", so at this moment we don't have a clear grasp on what distinguishes cases that work from cases that don't. We need to pursue this like a bloodhound and aggressively make as many cases as possible work transparently. This is a major asset of D over virtually all other languages. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 07, 2011 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 --- Comment #5 from David Simcha <dsimcha@yahoo.com> 2011-03-06 16:29:07 PST --- (In reply to comment #3) > (In reply to comment #2) > > So is this an WONTFIX, then? > > Unless there's an epiphany somewhere, yes. How would you suggest two hidden context pointers be handled? Is it clear that two context pointers are required (at least for this example)? Honestly, I don't know enough about the details of how DMD works under the hood to come up with a good answer, but my completely naive answer would be to pass the delegate context pointer in as a hidden argument between the explicit arguments and the hidden class instance pointer. The class instance pointer is still passed last (no special casing) and the delegate context pointer lives on the stack somewhere as a regular stack variable and gets passed in when needed. > > > Unfortunately it severely hurts my > > std.parallelism design in some use cases, and a workaround for it would be a > > significant PITA to implement, make the API uglier, and possibly be > > inefficient. > > I don't know enough about your design to offer help with that. Perhaps instead of an alias parameter, make fun explicitly a delegate? This would be the workaround, but I probably won't implement it because: 1. If I still keep alias parameters, I'll have to have two implementations of map(), reduce() and friends. This is ugly from both an API and an implementation perspective. 2. Delegates can't be inlined. Aliases can. 3. Delegates can only be instantiations of templates. Aliases can be templates. This means that a nested template function would have to be explicitly instantiated. This is ugly. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 07, 2011 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 --- Comment #6 from Walter Bright <bugzilla@digitalmars.com> 2011-03-06 22:18:04 PST --- (In reply to comment #4) > First, the compiler should figure out that add does not need a frame pointer and consider it a static inner function, not a delegate. Delegates and functions are different types. Deciding, based on the contents of a function body, whether it is a function or a delegate makes for non-obvious changes in type. Secondly, people are going to access outer variables from a nested function, and will not expect it to break their code. > Second, we need to agree that the reason you invoke is tied to the implementation - you use the same pointer for the class and for the hidden frame pointer, whereas of course there's no imposition to do so. Making them use the same ABI means that they have the same type and are interchangeable. This is a big deal. I don't think this will survive "a class member function pointer is a different type than a nested function pointer". > The hidden "this" parameter could go pretty much anywhere else. > One way or another we must fix this. Oddly, a number of similar uses do work > "by mistake", so at this moment we don't have a clear grasp on what > distinguishes cases that work from cases that don't. > We need to pursue this like a bloodhound and aggressively make as many cases as > possible work transparently. This is a major asset of D over virtually all > other languages. Consider if we add another type - a function pointer with two context pointers. Now we have quite a menagerie: 1. function pointer 2. function pointer with context pointer (delegate) 3. function pointer with two context pointers Is that really where we want to go? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 07, 2011 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 Rainer Schuetze <r.sagitario@gmx.de> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |r.sagitario@gmx.de --- Comment #7 from Rainer Schuetze <r.sagitario@gmx.de> 2011-03-07 00:35:26 PST --- This could be implemented with a single context pointer, if the this pointer of the Foo instance can be found through the stack frame pointer. In the example the pointer to foo is already there, but in the more general case, a hidden stack/closure variable needs to be used. I'm not sure how much it would complicate code generation, though. It could end up as a can of worms, e.g. having to deal with multiple aliases to different kind of context pointers. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 07, 2011 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 Brad Roberts <braddr@puremagic.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |braddr@puremagic.com --- Comment #8 from Brad Roberts <braddr@puremagic.com> 2011-03-07 01:19:35 PST --- (In reply to comment #6) > Consider if we add another type - a function pointer with two context pointers. Now we have quite a menagerie: > > 1. function pointer > 2. function pointer with context pointer (delegate) > 3. function pointer with two context pointers > > Is that really where we want to go? Yes. They're just function parameters. Define how they're passed and pass 'em. It doesn't need to be fancy or tricky. It's not particularly different from passing dynamic arrays having a well defined parameter layout. Just considered it just a tuple of two pointers. It's not rocket science. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
June 10, 2011 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 Kenji Hara <k.hara.pg@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |k.hara.pg@gmail.com --- Comment #9 from Kenji Hara <k.hara.pg@gmail.com> 2011-06-10 06:44:19 PDT --- My idea: doStuff receives a context pointer that points 'an array of context pointers'. Backend receives code like follows... uint doStuff(uint a, uint b, void** this) // not void* this { // (*this + 0) points the object Foo // (*this + 1) points the stack frame of main() //return fun(a, b); return fun(a, b, (*this + 1)); } Caller of doStuff have to create array of context pointers. void main(){ ... //foo.doStuff!add(1, 2); void*[2] thisarray = [(stack frame of main), foo]; doStuff(a, b, thisarray.ptr); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation