www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is std.typecons.Rebindable ever going to work for this?

reply Michel Fortin <michel.fortin michelf.com> writes:
I have a problem where I want to store rebindable references to other 
objects, but I also want to ensure those objects are immutable. 
Basically, the Rebindable template in std.typecons should do the job, 
but it appears that it does not work with forward references...

Going further, I've made this simple test case and I'm left wondering 
if there is a way for the compiler to make that work in the future. 
Basically, the definition of each class depends on the other class. Can 
the compiler instantiate a template using a partially defined class? 
One of the template has to be instantiate before the other, obviously.

import std.typecons;

class A {
	Rebindable!(const B) r;
}

class B {
	Rebindable!(const A) r;
}

I'm not sure if I really want to use this pattern; this is just an 
experiment I made. But it looks quite limiting not to be able to do 
that.

-- 
Michel Fortin
michel.fortin michelf.com
http://michelf.com/
Dec 17 2009
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 17 Dec 2009 08:35:31 -0500, Michel Fortin  
<michel.fortin michelf.com> wrote:

 I have a problem where I want to store rebindable references to other  
 objects, but I also want to ensure those objects are immutable.  
 Basically, the Rebindable template in std.typecons should do the job,  
 but it appears that it does not work with forward references...

 Going further, I've made this simple test case and I'm left wondering if  
 there is a way for the compiler to make that work in the future.  
 Basically, the definition of each class depends on the other class. Can  
 the compiler instantiate a template using a partially defined class? One  
 of the template has to be instantiate before the other, obviously.

 import std.typecons;

 class A {
 	Rebindable!(const B) r;
 }

 class B {
 	Rebindable!(const A) r;
 }

 I'm not sure if I really want to use this pattern; this is just an  
 experiment I made. But it looks quite limiting not to be able to do that.

Doing some tests, it appears that the issue is not strictly that you can't use a forward reference class as a template argument. This appears to work: struct S(T) { T t; } class A { S!B r; } class B { S!A r; } Adding this to S(T) makes it not work: struct S(T) if (is(T: Object)) { T t; } -Steve
Dec 17 2009
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-12-17 08:57:32 -0500, "Steven Schveighoffer" 
<schveiguy yahoo.com> said:

 Adding this to S(T) makes it not work:
 
 struct S(T) if (is(T: Object))
 {
     T t;
 }

Yes indeed. Interestingly you can change it to is(T == class) and now it works again! There seem to be no difference between is(T : Object) and is(T == class), except that the former prevents forward declarations. I guess it means that is(T : Object) should not be used. I made a quick search and found 10 occurrences of it in Phobos. The same problem happens with template arguments: "template S(T : Object)" does not work with forward declarations. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 17 2009
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Michel Fortin wrote:
 I have a problem where I want to store rebindable references to other 
 objects, but I also want to ensure those objects are immutable. 
 Basically, the Rebindable template in std.typecons should do the job, 
 but it appears that it does not work with forward references...
 
 Going further, I've made this simple test case and I'm left wondering if 
 there is a way for the compiler to make that work in the future. 
 Basically, the definition of each class depends on the other class. Can 
 the compiler instantiate a template using a partially defined class? One 
 of the template has to be instantiate before the other, obviously.
 
 import std.typecons;
 
 class A {
     Rebindable!(const B) r;
 }
 
 class B {
     Rebindable!(const A) r;
 }
 
 I'm not sure if I really want to use this pattern; this is just an 
 experiment I made. But it looks quite limiting not to be able to do that.
 

This is a bug. Could you please file it in bugzilla? Andrei
Dec 17 2009
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-12-17 10:51:04 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 Michel Fortin wrote:
 I have a problem where I want to store rebindable references to other 
 objects, but I also want to ensure those objects are immutable. 
 Basically, the Rebindable template in std.typecons should do the job, 
 but it appears that it does not work with forward references...
 
 Going further, I've made this simple test case and I'm left wondering 
 if there is a way for the compiler to make that work in the future. 
 Basically, the definition of each class depends on the other class. Can 
 the compiler instantiate a template using a partially defined class? 
 One of the template has to be instantiate before the other, obviously.
 
 import std.typecons;
 
 class A {
     Rebindable!(const B) r;
 }
 
 class B {
     Rebindable!(const A) r;
 }
 
 I'm not sure if I really want to use this pattern; this is just an 
 experiment I made. But it looks quite limiting not to be able to do 
 that.
 

This is a bug. Could you please file it in bugzilla?

Here: <http://d.puremagic.com/issues/show_bug.cgi?id=3625> It turns out the 'get' member of Rebindable is unusable too (unless you're in the same module). It's already reported: <http://d.puremagic.com/issues/show_bug.cgi?id=3318>. In fact, I'd have liked to get rid of 'get' in Rebindable and use alias this instead so that it behaves like any other object reference, but I'm running into another problem, so that'll have to wait. Bug: <http://d.puremagic.com/issues/show_bug.cgi?id=3626> -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 17 2009