www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Extending "scope"

reply Brian White <bcwhite pobox.com> writes:
I wrote something about "GC vs delete", but after thinking about it some 
more, how about this...

There seems to be a fundamental conflict between RAII and the garbage 
collector.  You can assign a new object to a "scope" variable to cause 
it to get destructed without waiting for the GC, but what about objects 
within that?  For example:

class tBar {
     this()
     {
         writeln("a bar has been constructed");
     }
     ~this()
     {
         writeln("a bar has been destructed");
     }
}

class tFoo {
     scope tBar bar;

     this()
     {
         bar = new tBar();
         writeln("a foo has been constructed");
     }
     ~this()
     {
         delete bar;
         writeln("a foo has been destructed");
     }
}

unittest {
     auto foo = new tFoo();
}


If you run this, you'll get:

a bar has been constructed
a foo has been constructed

At some point, you _may_ also get:

a bar has been destructed
a foo has been destructed


When it comes to RAII, that's not enough.  Walter has allowed us to 
specify a class as being "scope" which requires you to create them with 
"scope auto foo = new tFoo()".  However, if I also add that property to 
"tBar", it won't compile.

scope class tBar {
     this()
     {
         writeln("a bar has been constructed");
     }
     ~this()
     {
         writeln("a bar has been destructed");
     }
}

scope class tFoo {
     tBar bar;

     this()
     {
         bar = new tBar();
         writeln("a foo has been constructed");
     }
     ~this()
     {
         delete bar;
         writeln("a foo has been destructed");
     }
}

unittest {
     scope auto foo = new tFoo();
}

$ dmd ...
test.d(32): variable socket_test.tFoo.bar globals, statics, fields, 
manifest constants, ref and out parameters cannot be auto
test.d(32): variable socket_test.tFoo.bar reference to scope class must 
be scope

Nor can I declare a member variable "scope tBar bar" within class tFoo. 
  In other words, it's not possible to embed one enforced RAII object 
within another.


What do others think about extending "scope" to allow it to be applied 
to member data?  They would by default be set to "null" but have the 
requirement that they must be set exactly once in the constructor and 
nowhere else.  They would also be deleted automatically during the 
destructor.

Or...  Is there a different way to accomplish this?

-- Brian
Apr 06 2008
next sibling parent reply "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Sun, 06 Apr 2008 09:36:15 +0100, Brian White <bcwhite pobox.com> wrote:

 I wrote something about "GC vs delete", but after thinking about it some  
 more, how about this...

 There seems to be a fundamental conflict between RAII and the garbage  
 collector.  You can assign a new object to a "scope" variable to cause  
 it to get destructed without waiting for the GC, but what about objects  
 within that?  For example:

Apr 06 2008
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Bruce Adams" <tortoise_74 yeah.who.co.uk> wrote in message 
news:op.t86qykboxikks4 starquake.cybernetics...
 On Sun, 06 Apr 2008 09:36:15 +0100, Brian White <bcwhite pobox.com> wrote:

 I wrote something about "GC vs delete", but after thinking about it some 
 more, how about this...

 There seems to be a fundamental conflict between RAII and the garbage 
 collector.  You can assign a new object to a "scope" variable to cause 
 it to get destructed without waiting for the GC, but what about objects 
 within that?  For example:


Maybe it should be a paintable delete :P
Apr 06 2008
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Bruce Adams:
 You want a transitive delete. :)

And it sounds like an interesting feature. Bye, bearophile
Apr 06 2008
prev sibling next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Brian White" <bcwhite pobox.com> wrote in message 
news:fta21v$1ane$1 digitalmars.com...
I wrote something about "GC vs delete", but after thinking about it some 
more, how about this...

 There seems to be a fundamental conflict between RAII and the garbage 
 collector.  You can assign a new object to a "scope" variable to cause it 
 to get destructed without waiting for the GC, but what about objects 
 within that?  For example:

 class tBar {
     this()
     {
         writeln("a bar has been constructed");
     }
     ~this()
     {
         writeln("a bar has been destructed");
     }
 }

 class tFoo {
     scope tBar bar;

     this()
     {
         bar = new tBar();
         writeln("a foo has been constructed");
     }
     ~this()
     {
         delete bar;
         writeln("a foo has been destructed");
     }
 }

 unittest {
     auto foo = new tFoo();
 }


 If you run this, you'll get:

 a bar has been constructed
 a foo has been constructed

 At some point, you _may_ also get:

 a bar has been destructed
 a foo has been destructed


 When it comes to RAII, that's not enough.  Walter has allowed us to 
 specify a class as being "scope" which requires you to create them with 
 "scope auto foo = new tFoo()".  However, if I also add that property to 
 "tBar", it won't compile.

 scope class tBar {
     this()
     {
         writeln("a bar has been constructed");
     }
     ~this()
     {
         writeln("a bar has been destructed");
     }
 }

 scope class tFoo {
     tBar bar;

     this()
     {
         bar = new tBar();
         writeln("a foo has been constructed");
     }
     ~this()
     {
         delete bar;
         writeln("a foo has been destructed");
     }
 }

 unittest {
     scope auto foo = new tFoo();
 }

 $ dmd ...
 test.d(32): variable socket_test.tFoo.bar globals, statics, fields, 
 manifest constants, ref and out parameters cannot be auto
 test.d(32): variable socket_test.tFoo.bar reference to scope class must be 
 scope

 Nor can I declare a member variable "scope tBar bar" within class tFoo. In 
 other words, it's not possible to embed one enforced RAII object within 
 another.


 What do others think about extending "scope" to allow it to be applied to 
 member data?  They would by default be set to "null" but have the 
 requirement that they must be set exactly once in the constructor and 
 nowhere else.  They would also be deleted automatically during the 
 destructor.

 Or...  Is there a different way to accomplish this?

 -- Brian

I think you're the 318th person to suggest this. I might be talking out of you-know-where but I think I remember Walter mentioning that this is in the cards for D2.
Apr 06 2008
parent Brian White <bcwhite pobox.com> writes:
 What do others think about extending "scope" to allow it to be applied to 
 member data?  They would by default be set to "null" but have the 
 requirement that they must be set exactly once in the constructor and 
 nowhere else.  They would also be deleted automatically during the 
 destructor.

I think you're the 318th person to suggest this. I might be talking out of you-know-where but I think I remember Walter mentioning that this is in the cards for D2.

Well... I'm fairly new here. :-) If it's in the cards for D2, it's not currently implemented there since that's the compiler I'm using. I forgot to mention that of course only scope classes could have scope members, but I think that's fairly obvious. -- Brian
Apr 06 2008
prev sibling parent davidl <davidl 126.com> writes:
在 Sun, 06 Apr 2008 16:36:15 +0800,Brian White <bcwhite pobox.com> 写道:

I posted an enhancement bug for this particular issue. don't remember the  
bugid.
I suggest the scope class member as a local initialized stuff that's a  
struct like stuff.



-- 
使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
Apr 08 2008