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