www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - lambdas and function literals in classes

reply "John Colvin" <john.loughran.colvin gmail.com> writes:
JS asked about this in the main group, but here is more 
appropriate and I'm quite interested myself.

Can someone explain the rationale behind this:

class A
{
     auto a = (){}; 		//Lambda not allowed
     auto b = function(){};	//Function allowed
     auto c = delegate(){};	//Delegate not allowed
}

A guess:

Delegate's aren't allowed as members due their context pointer 
(why???), lambdas are assumed to be delegates unless they are 
proved to not need context (and dmd is sucking at proving that).
Jul 09 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Tuesday, 9 July 2013 at 10:50:02 UTC, John Colvin wrote:
 JS asked about this in the main group, but here is more 
 appropriate and I'm quite interested myself.

 Can someone explain the rationale behind this:

 class A
 {
     auto a = (){}; 		//Lambda not allowed
     auto b = function(){};	//Function allowed
     auto c = delegate(){};	//Delegate not allowed
 }

 A guess:

 Delegate's aren't allowed as members due their context pointer 
 (why???), lambdas are assumed to be delegates unless they are 
 proved to not need context (and dmd is sucking at proving that).
Error message is actually misleading here, because this compiles: class A { void delegate() a; } void main() { auto a = new A(); a.a = () {}; } So this has something to do with _initialization_ of class members with delegates/lambdas, not their very existence.
Jul 09 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Dicebot:

 So this has something to do with _initialization_ of class 
 members with delegates/lambdas, not their very existence.
So is it worth adding this diagnostic bug report in Bugzilla? class Foo { void delegate() dg1; void delegate() dg2 = delegate(){}; this() { this.dg1 = (){}; } } void main() { auto f = new Foo; } DMD 2.064alpha gives: temp.d(3): Error: delegate temp.Foo.__dgliteral1 function literals cannot be class members temp.d(3): Error: cannot implicitly convert expression (__dgliteral1) of type _error_ delegate() to void delegate() Bye, bearophile
Jul 09 2013
parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 9 July 2013 at 11:16:39 UTC, bearophile wrote:
 So is it worth adding this diagnostic bug report in Bugzilla?

 ...
I think yes. It should either just work or provide error message that actually explains the reasoning. Probably Don can clarify this as static initialization of a field feels like his domain.
Jul 09 2013
prev sibling parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 07/09/13 12:50, John Colvin wrote:
 JS asked about this in the main group, but here is more appropriate and I'm
quite interested myself.
Function/delegate *literals* in aggregates are not accepted by the compiler. It's just a compiler issue; iirc the frontend recently got a bit smarter about figuring out what is/isn't a delegate, so maybe at some point the restriction will be gone. Right now, everybody runs into this, and has to work around by inventing dummy names for the literals. Ie struct S { enum a = { return 42; }(); } does not work.You have to use struct S { static ugh() { return 42; }; enum a = ugh(); } which of course litters the namespace and obfuscates what's happening. The enum a = { return 42; }(); line will work outside of the struct/class/whatever. For this to work the compiler would have figure out that the function literal really is just a function literal, ie does not access any field of the struct and does not need any context pointer. Which is possible, but does not currently happen. It's also not possible to /explicitly/ specify - there's no way to mark *just* the literal as "static". struct S { static enum a = { return 42; }(); } Works - but that's not enough: struct S { static mixin({ return "int a;"; }()); // oops, 'a' is static. } IIRC this issue is already reported somewhere in bugzilla. artur
Jul 09 2013
next sibling parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 9 July 2013 at 12:32:55 UTC, Artur Skawina wrote:
 On 07/09/13 12:50, John Colvin wrote:
 JS asked about this in the main group, but here is more 
 appropriate and I'm quite interested myself.
Function/delegate *literals* in aggregates are not accepted by the compiler.
Probably calling those "function/delegate literals at aggregate _scope_" is a more precise thing to do. Because current error message sounds rather ambiguous.
Jul 09 2013
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 07/09/2013 02:32 PM, Artur Skawina wrote:
 IIRC this issue is already reported somewhere in bugzilla.
http://d.puremagic.com/issues/show_bug.cgi?id=7653
Jul 09 2013