Thread overview
lambdas and function literals in classes
Jul 09, 2013
John Colvin
Jul 09, 2013
Dicebot
Jul 09, 2013
bearophile
Jul 09, 2013
Dicebot
Jul 09, 2013
Artur Skawina
Jul 09, 2013
Dicebot
Jul 09, 2013
Timon Gehr
July 09, 2013
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).
July 09, 2013
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.
July 09, 2013
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
July 09, 2013
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.
July 09, 2013
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
July 09, 2013
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.
July 09, 2013
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