On Fri, 30 Sep 2011 14:00:36 -0400, Michel Fortin <michel.for...@michelf.com> wrote:

On 2011-09-30 17:46:13 +0000, "Steven Schveighoffer" <schvei...@yahoo.com> said:

On Fri, 30 Sep 2011 13:38:31 -0400, Michel Fortin <michel.for...@michelf.com> wrote:

On 2011-09-29 14:54:24 +0000, "Steven Schveighoffer" <schvei...@yahoo.com> said:

I just thought of an interesting way to make a logical const object without casts. It requires a little extra storage, but works without changes to the current compiler (and requires no casts).
 Here's the code, then I'll talk about the implications:
 import std.stdio;
 class D
{
     D getme() { return this;}
     void foo() {writeln("mutable!");}
}
 class C
{
     D delegate() d;
     this()
     {
       auto dinst = new D;
       this.d = &dinst.getme;
     }
     void bar() const { d().foo();}
}
 void main()
{
     auto c = new C;
     c.bar();
}
 outputs:
 mutable!
So how does it work? It works because delegates and especially the delegate data is *not* affected by const. So even when C is temporarily cast to const, the delegate is not affected (i.e. it's context pointer is not temporarily cast to const). Doesn't this poke holes in const? Of course it does, but no more holes than are present via another logical const scheme (i.e. using a globally stored AA to retrieve the data).
This is a hole in the transitive const, because the delegate contains a pointer to mutable data. It also is a potential source of of low level races since returning that type from a pure function could make it immutable, which can then make this mutable data accessible to multiple threads with no synchronization or atomics to protect the data's integrity.
Simen Kjaeraas and Christophe brought up the same points. I filed a bug on it:
 http://d.puremagic.com/issues/show_bug.cgi?id=6741

Interesting proposal. You realize if we had a true 'mutable' storage class for class members it could obey the same rule as you propose in that bug report: it should be illegal to cast a mutable-containing object or struct to immutable implicitly. An explicit cast should be required.

Yes, but the benefit of the proposal is -- it already works in the current compiler :) You have a monstrous hill to climb to convince Walter to *add* mutable storage class, but we don't even have to ask for this one, it works today.

Also, if we had shared delegates -- delegates which are guarantied to only manipulate shared data -- we could allow the class that contains a shared delegate to be implicitly converted to immutable.

I'd like to avoid the complication of having any attributes that apply to the context pointer. I like how delegates just fit in anywhere, no matter what the context pointer type is (or its constancy).

-Steve

Reply via email to