www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - delegate as memeber

reply deadalnix <deadalnix gmail.com> writes:
struct stuff {
	private Exception delegate() exceptionBuilder = delegate Exception() {
		return new Exception("foobar");
	};
}

The following piece of code trigger a compiler error : delegate 
module.stuff.__dgliteral1 function literals cannot be class members

Why is that ? Is it a bug or a feature ?
Feb 21 2012
next sibling parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote:
 struct stuff {
 	private Exception delegate() exceptionBuilder = delegate 
 Exception() {
 		return new Exception("foobar");
 	};
 }

 The following piece of code trigger a compiler error : delegate 
 module.stuff.__dgliteral1 function literals cannot be class 
 members

 Why is that ? Is it a bug or a feature ?

Delegates contain a context pointer. Your delegate literal has no context. You can't initialize it with the address of a method, either. For struct methods, the context pointer is a pointer to the structure. You can't have a .init that contains a pointer to an instance. You probably want to use a function literal.
Feb 21 2012
parent reply deadalnix <deadalnix gmail.com> writes:
Le 21/02/2012 16:32, Vladimir Panteleev a écrit :
 On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote:
 struct stuff {
 private Exception delegate() exceptionBuilder = delegate Exception() {
 return new Exception("foobar");
 };
 }

 The following piece of code trigger a compiler error : delegate
 module.stuff.__dgliteral1 function literals cannot be class members

 Why is that ? Is it a bug or a feature ?

Delegates contain a context pointer. Your delegate literal has no context. You can't initialize it with the address of a method, either. For struct methods, the context pointer is a pointer to the structure. You can't have a .init that contains a pointer to an instance. You probably want to use a function literal.

It doesn't work with function either. But I need delegate here. The default one doesn't require a context, but isn't it possible to pass null as a context, as none is needed ? This value can be changer later, and definitively require to be a delegate.
Feb 21 2012
next sibling parent deadalnix <deadalnix gmail.com> writes:
Le 22/02/2012 03:59, Vladimir Panteleev a écrit :
 On Tuesday, 21 February 2012 at 15:41:58 UTC, deadalnix wrote:
 Le 21/02/2012 16:32, Vladimir Panteleev a écrit :
 On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote:
 struct stuff {
 private Exception delegate() exceptionBuilder = delegate Exception() {
 return new Exception("foobar");
 };
 }

 The following piece of code trigger a compiler error : delegate
 module.stuff.__dgliteral1 function literals cannot be class members

 Why is that ? Is it a bug or a feature ?

Delegates contain a context pointer. Your delegate literal has no context. You can't initialize it with the address of a method, either. For struct methods, the context pointer is a pointer to the structure. You can't have a .init that contains a pointer to an instance. You probably want to use a function literal.

It doesn't work with function either. But I need delegate here. The default one doesn't require a context, but isn't it possible to pass null as a context, as none is needed ? This value can be changer later, and definitively require to be a delegate.

struct stuff { private Exception function() exceptionBuilder = &defaultExceptionBuilder; private static Exception defaultExceptionBuilder() { return new Exception("foobar"); }; }

This look very promizing !!! I'll investigate in that direction. Thank you very much for the hint.
Feb 22 2012
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/21/2012 07:43 AM, deadalnix wrote:
 Le 21/02/2012 16:32, Vladimir Panteleev a écrit :
 On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote:
 struct stuff {
 private Exception delegate() exceptionBuilder = delegate Exception() {
 return new Exception("foobar");
 };
 }

 The following piece of code trigger a compiler error : delegate
 module.stuff.__dgliteral1 function literals cannot be class members

 Why is that ? Is it a bug or a feature ?

Delegates contain a context pointer. Your delegate literal has no context. You can't initialize it with the address of a method, either. For struct methods, the context pointer is a pointer to the structure. You can't have a .init that contains a pointer to an instance. You probably want to use a function literal.

It doesn't work with function either. But I need delegate here. The default one doesn't require a context, but isn't it possible to pass null as a context, as none is needed ? This value can be changer later, and definitively require to be a delegate.

Could std.functional.toDelegate be helpful here? http://dlang.org/phobos/std_functional.html#toDelegate Ali
Feb 22 2012
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
A possible workaround is to initialize the delegate
in the object's constructor.
Feb 21 2012
parent reply deadalnix <deadalnix gmail.com> writes:
Le 21/02/2012 16:48, Adam D. Ruppe a écrit :
 A possible workaround is to initialize the delegate
 in the object's constructor.

It is a struct. And struct don't have default constructor. It lead to very segfault prone code (I did try that).
Feb 21 2012
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2012-02-21 16:55, deadalnix wrote:
 Le 21/02/2012 16:48, Adam D. Ruppe a écrit :
 A possible workaround is to initialize the delegate
 in the object's constructor.

It is a struct. And struct don't have default constructor. It lead to very segfault prone code (I did try that).

You can implement a static opCall and use that instead of the constructor. -- /Jacob Carlborg
Feb 21 2012
next sibling parent deadalnix <deadalnix gmail.com> writes:
Le 21/02/2012 18:46, Jacob Carlborg a écrit :
 On 2012-02-21 16:55, deadalnix wrote:
 Le 21/02/2012 16:48, Adam D. Ruppe a écrit :
 A possible workaround is to initialize the delegate
 in the object's constructor.

It is a struct. And struct don't have default constructor. It lead to very segfault prone code (I did try that).

You can implement a static opCall and use that instead of the constructor.

It's a cheap replacement because it doesn't allow to new.
Feb 22 2012
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 21/02/2012 17:46, Jacob Carlborg wrote:
 On 2012-02-21 16:55, deadalnix wrote:

 You can implement a static opCall and use that instead of the constructor.

But you don't have to call a static opCall. You can just declare a struct instance without any initialisation. Presumably half the point is to ensure that exceptionBuilder is still initialised in such cases. Stewart.
Feb 25 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 02/25/2012 03:32 PM, Stewart Gordon wrote:
 On 21/02/2012 17:46, Jacob Carlborg wrote:
 On 2012-02-21 16:55, deadalnix wrote:

 You can implement a static opCall and use that instead of the
 constructor.

But you don't have to call a static opCall. You can just declare a struct instance without any initialisation. Presumably half the point is to ensure that exceptionBuilder is still initialised in such cases. Stewart.

struct exceptionBuilder{ disable this(); disable enum init=0; static exceptionBuilder opCall(...){...} }
Feb 25 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 02/25/2012 07:23 PM, Artur Skawina wrote:
 On 02/25/12 15:37, Timon Gehr wrote:
 On 02/25/2012 03:32 PM, Stewart Gordon wrote:
 On 21/02/2012 17:46, Jacob Carlborg wrote:
 On 2012-02-21 16:55, deadalnix wrote:

 You can implement a static opCall and use that instead of the
 constructor.

But you don't have to call a static opCall. You can just declare a struct instance without any initialisation. Presumably half the point is to ensure that exceptionBuilder is still initialised in such cases. Stewart.

struct exceptionBuilder{ disable this(); disable enum init=0; static exceptionBuilder opCall(...){...} }

Too bad this doesn't work when opCall takes args. IOW, "S(2)" results in Error: constructor m.S.this () is not callable using argument types (int) Error: constructor m.S.this is not callable because it is annotated with disable Error: expected 0 arguments, not 1 for non-variadic function type ref S() Removing the disabled 'this()' makes the error go away and the right opCall() gets called. artur

Well, that is a bug. http://d.puremagic.com/issues/show_bug.cgi?id=6036
Feb 25 2012
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 02/25/12 15:37, Timon Gehr wrote:
 On 02/25/2012 03:32 PM, Stewart Gordon wrote:
 On 21/02/2012 17:46, Jacob Carlborg wrote:
 On 2012-02-21 16:55, deadalnix wrote:

 You can implement a static opCall and use that instead of the
 constructor.

But you don't have to call a static opCall. You can just declare a struct instance without any initialisation. Presumably half the point is to ensure that exceptionBuilder is still initialised in such cases. Stewart.

struct exceptionBuilder{ disable this(); disable enum init=0; static exceptionBuilder opCall(...){...} }

Too bad this doesn't work when opCall takes args. IOW, "S(2)" results in Error: constructor m.S.this () is not callable using argument types (int) Error: constructor m.S.this is not callable because it is annotated with disable Error: expected 0 arguments, not 1 for non-variadic function type ref S() Removing the disabled 'this()' makes the error go away and the right opCall() gets called. artur
Feb 25 2012
prev sibling next sibling parent reply Mantis <mail.mantis.88 gmail.com> writes:
21.02.2012 17:24, deadalnix пишет:
 struct stuff {
 private Exception delegate() exceptionBuilder = delegate Exception() {
 return new Exception("foobar");
 };
 }

 The following piece of code trigger a compiler error : delegate 
 module.stuff.__dgliteral1 function literals cannot be class members

 Why is that ? Is it a bug or a feature ?

The compiler expects member initializers to be known at compile-time. Since delegate carries closure, and closure is a run-time phenomena, you cannot put it there. That's how I understand it, and I might be wrong. Anyway, something like this is possible as a workaround: struct Foo { private Exception dg() { if( m_Dg ) return m_Dg(); return new Exception( "foobar" ); } private Exception delegate() m_Dg = null; }
Feb 21 2012
parent deadalnix <deadalnix gmail.com> writes:
Le 21/02/2012 17:30, Mantis a écrit :
 21.02.2012 17:24, deadalnix пишет:
 struct stuff {
 private Exception delegate() exceptionBuilder = delegate Exception() {
 return new Exception("foobar");
 };
 }

 The following piece of code trigger a compiler error : delegate
 module.stuff.__dgliteral1 function literals cannot be class members

 Why is that ? Is it a bug or a feature ?

The compiler expects member initializers to be known at compile-time. Since delegate carries closure, and closure is a run-time phenomena, you cannot put it there. That's how I understand it, and I might be wrong. Anyway, something like this is possible as a workaround: struct Foo { private Exception dg() { if( m_Dg ) return m_Dg(); return new Exception( "foobar" ); } private Exception delegate() m_Dg = null; }

I think this the best solution after all. But still I think the original code should be an error only if it use data out of the delegate scope. If it doesn't, frame pointer doesn't matter and null can be passed.
Feb 21 2012
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Feb 21, 2012 at 08:01:18PM +0100, deadalnix wrote:
[...]
 But still I think the original code should be an error only if it
 use data out of the delegate scope. If it doesn't, frame pointer
 doesn't matter and null can be passed.

You could file an enhancement request, if one hasn't already been filed. T -- I'm still trying to find a pun for "punishment"...
Feb 21 2012
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Tuesday, 21 February 2012 at 15:41:58 UTC, deadalnix wrote:
 Le 21/02/2012 16:32, Vladimir Panteleev a écrit :
 On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote:
 struct stuff {
 private Exception delegate() exceptionBuilder = delegate 
 Exception() {
 return new Exception("foobar");
 };
 }

 The following piece of code trigger a compiler error : 
 delegate
 module.stuff.__dgliteral1 function literals cannot be class 
 members

 Why is that ? Is it a bug or a feature ?

Delegates contain a context pointer. Your delegate literal has no context. You can't initialize it with the address of a method, either. For struct methods, the context pointer is a pointer to the structure. You can't have a .init that contains a pointer to an instance. You probably want to use a function literal.

It doesn't work with function either. But I need delegate here. The default one doesn't require a context, but isn't it possible to pass null as a context, as none is needed ? This value can be changer later, and definitively require to be a delegate.

struct stuff { private Exception function() exceptionBuilder = &defaultExceptionBuilder; private static Exception defaultExceptionBuilder() { return new Exception("foobar"); }; }
Feb 21 2012
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 02/21/2012 04:24 PM, deadalnix wrote:
 struct stuff {
 private Exception delegate() exceptionBuilder = delegate Exception() {
 return new Exception("foobar");
 };
 }

 The following piece of code trigger a compiler error : delegate
 module.stuff.__dgliteral1 function literals cannot be class members

 Why is that ? Is it a bug or a feature ?

Bug or not, It is an annoying limitation.
Feb 22 2012
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Feb 22, 2012 at 12:42:44PM +0100, deadalnix wrote:
 Le 22/02/2012 03:59, Vladimir Panteleev a crit :

struct stuff {
private Exception function() exceptionBuilder =
&defaultExceptionBuilder;

private static Exception defaultExceptionBuilder() {
return new Exception("foobar");
};
}

This look very promizing !!! I'll investigate in that direction. Thank you very much for the hint.

But doesn't this only work for function pointers? I don't think you can later assign a *delegate* to exceptionBuilder. They are different types (delegates need fat pointers, won't fit in a function pointer). T -- Trying to define yourself is like trying to bite your own teeth. -- Alan Watts
Feb 22 2012