www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - how to declare a self-referencing type?

reply "Kris" <fu bar.com> writes:
I need to declare a type of delegate that returns an instance of the same
type. Here's my attempt:

#  alias DG delegate (int x) DG;

#  DG someMethod (int x)
#  {
#       return &someMethod;
#  }

Compiler does not like the recursive nature of that alias declaration. A
pair of mutual aliases don't compile either; nor does typedef. A solution
would be much appreciated ...
May 20 2005
next sibling parent reply John Reimer <brk_6502 yahoo.com> writes:
Kris wrote:
 I need to declare a type of delegate that returns an instance of the same
 type. Here's my attempt:
 
 #  alias DG delegate (int x) DG;
 
 #  DG someMethod (int x)
 #  {
 #       return &someMethod;
 #  }
 
 Compiler does not like the recursive nature of that alias declaration. A
 pair of mutual aliases don't compile either; nor does typedef. A solution
 would be much appreciated ...
 
 

Isn't it impossible since the this pointer is not accessible from within the delegate? Perhaps you were hoping for an exception to be made in this case? -John
May 20 2005
parent reply "Kris" <fu bar.com> writes:
The example is contrived ~ but delegates do have 'this' access (functions
don't). It's the DG declaration that's the issue <g>


"John Reimer" <brk_6502 yahoo.com> wrote in message
news:d6mfqb$296a$1 digitaldaemon.com...
 Kris wrote:
 I need to declare a type of delegate that returns an instance of the


 type. Here's my attempt:

 #  alias DG delegate (int x) DG;

 #  DG someMethod (int x)
 #  {
 #       return &someMethod;
 #  }

 Compiler does not like the recursive nature of that alias declaration. A
 pair of mutual aliases don't compile either; nor does typedef. A


 would be much appreciated ...

Isn't it impossible since the this pointer is not accessible from within the delegate? Perhaps you were hoping for an exception to be made in this case? -John

May 20 2005
parent John Reimer <brk_6502 yahoo.com> writes:
Heh, yeah... I know "this" is part of delegates.  I just got a little 
confused as to what access a dg has to "this" internally. I should have 
checked that information before posting. Pardon my response.

-JJR

Kris wrote:
 The example is contrived ~ but delegates do have 'this' access (functions
 don't). It's the DG declaration that's the issue <g>
 
 
 "John Reimer" <brk_6502 yahoo.com> wrote in message
 news:d6mfqb$296a$1 digitaldaemon.com...
 
Kris wrote:

I need to declare a type of delegate that returns an instance of the


same
type. Here's my attempt:

#  alias DG delegate (int x) DG;

#  DG someMethod (int x)
#  {
#       return &someMethod;
#  }

Compiler does not like the recursive nature of that alias declaration. A
pair of mutual aliases don't compile either; nor does typedef. A


solution
would be much appreciated ...

Isn't it impossible since the this pointer is not accessible from within the delegate? Perhaps you were hoping for an exception to be made in this case? -John


May 21 2005
prev sibling parent reply Burton Radons <burton-radons smocky.com> writes:
Kris wrote:
 I need to declare a type of delegate that returns an instance of the same
 type. Here's my attempt:
 
 #  alias DG delegate (int x) DG;
 
 #  DG someMethod (int x)
 #  {
 #       return &someMethod;
 #  }
 
 Compiler does not like the recursive nature of that alias declaration. A
 pair of mutual aliases don't compile either; nor does typedef. A solution
 would be much appreciated ...

Thanks, my brain just exploded. I don't see how it's possible, or how it could possibly be possible. If the compiler were lazy about typing, sure, but this returns a delegate which can infinitely return more delegates to any depth; the compiler must expand the return type, which means it would be working for infinity. It can't just assign "return_type" to "this". You can force the compiler to be lazy by wrapping it with a class or struct: alias DG delegate (int x) DDG; struct DG { DDG method; DG opCall (int x) { return method (x); } } DG toDG (DDG method) { DG result; result.method = method; return result; } int main () { DG otherMethod (int x) { printf ("Yar %d\n", x); } DG someMethod (int x) { printf ("Wee %d!\n", x); return toDG (&otherMethod); } DG dg = toDG (&someMethod); dg (4) (7); return 0; }
May 20 2005
next sibling parent kris <fu bar.org> writes:
 Thanks, my brain just exploded.

I thought it was an interesting one to contemplate, but didn't expect anything quite that spectacular :)
 
 I don't see how it's possible, or how it could possibly be possible.  If 
 the compiler were lazy about typing, sure, but this returns a delegate 
 which can infinitely return more delegates to any depth; the compiler 
 must expand the return type, which means it would be working for 
 infinity.  It can't just assign "return_type" to "this".

Yeah; that's where I'd arrived at too.
 You can force the compiler to be lazy by wrapping it with a class or 
 struct:
 
 alias DG delegate (int x) DDG;
 
 struct DG
 {
     DDG method;
 
     DG opCall (int x)
     {
         return method (x);
     }
 }
 
 DG toDG (DDG method)
 {
     DG result;
 
     result.method = method;
     return result;
 }
 
 int main ()
 {
     DG otherMethod (int x)
     {
         printf ("Yar %d\n", x);
     }
 
     DG someMethod (int x)
     {
         printf ("Wee %d!\n", x);
         return toDG (&otherMethod);
     }
 
     DG dg = toDG (&someMethod);
 
     dg (4) (7);
     return 0;
 }

Good one; BTW ~ I must check out smocky.com (in you email addr). It's a great name <g>
May 21 2005
prev sibling parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Burton Radons wrote:
 Thanks, my brain just exploded.
 
 I don't see how it's possible, or how it could possibly be possible.  If 
 the compiler were lazy about typing, sure, but this returns a delegate 
 which can infinitely return more delegates to any depth; the compiler 
 must expand the return type, which means it would be working for 
 infinity.  It can't just assign "return_type" to "this".

It is conceivable, but perhaps not within C's typing structure. The language could support exactly what Kris proposed: recursive types, where one of the elements of a type (such as the return value) could be the type itself. However, that would probably require some substantial rethought in the compiler. At least, it would require rethought of the language. You get additional problems, like what happens if the recursion is not direct. If you got this right, this would count as something that D could do that C cannot (at least, not easily). Sort of like delegates :)
 You can force the compiler to be lazy by wrapping it with a class or 
 struct:

Drat! That was the solution I was going to propose. I ran across this problem a while ago in a library where I was implementing streams using callbacks; I wanted the get() callback to return the next get(), which might be null, or might be the same type as get(). Of course, it didn't work, so I ended up with a struct, like you propose.
May 23 2005