Walter is right about transitive readonly - here's the alternative
Christopher Wright
dhasenan at gmail.com
Thu Sep 13 07:02:11 PDT 2007
Janice Caron wrote something brilliant:
> We're going to need three new keywords, and a slightly new way of doing things.
>
> So, let's take this one step at a time...
>
> B b;
> int n = b.a.x; /* OK */
> int n = b.a.y; /* OK */
> int n = b.shared_a.x; /* Error */
> int n = b.shared_a.y; /* Error */
>
> You cannot access the member variables of something declared shared -
> not even to /read/. To do so is a compile time error. (And I stress,
> compile time. It's nice to have your thread-safety ensured at
> compile-time).
>
> So how do you read B's shared member variables? Well, that's where the
> second new keyword comes in - "readable"
>
> scope a = readable(b.shared_a);
> int n = a.x; /* OK - reads b.shared_a.x */
> int m = a.y; /* OK - reads b.shared_a.y */
>
> a.x = 4; /* Error - a is readonly */
> a.y = 4; /* Error - a is readonly */
>
> To write to b.shared_a, you need the third keyword. You guessed it - "writable".
>
> scope a = writable(b.shared_a);
> int n = a.x; /* OK - reads b.shared_a.x */
> a.y = n; /* OK - assigns b.shared_a.y */
>
> Again, a is a scope variable. That's because writable obtains an
> exclusive-access mutex, which must be released when a goes out of
> scope by any means.
>
> - - - - how does this help with const? - - - -
>
> Because shared variables are threadsafe, it is now harmless regard
> them as mutable. This allows to to re-introduce the concept of
> "logical constness" to D ... but only in a threadsafe way. Like this:
>
> class Shape
> {
> shared class Raster raster_s;
> abstract void draw();
> }
>
> class Rectangle
> {
> int x0, y0, x1, y1;
>
> void draw()
> {
> scope raster = writable(raster_s);
> raster.drawRectangle(x0,y0,x1,y1);
> }
> }
>
> const Rectangle r;
> r.draw(); /* OK */
>
> Voila!
The only thing that concerns me is that now you can make a Rectangle
class that's not logically const even when it's declared const. That is,
you could have a class RectangleImplementation that the Rectangle treats
as a writeable shared object. Then you could have a const Rectangle
where you can modify its properties at will.
That's a way to provide the 'mutable' keyword, but it's so ugly that I
would shoot anyone who did that in any code I owned. :P
I'm really in favor of separating logical constness from thread safety.
And I was thinking that using pure for the thread safety and const for
everything else was the way to go, but maybe we want a 'threadsafe'
keyword, too:
- A pure function is by definition threadsafe and const. There are
other optimizations that can be made for pure functions. This is what
Walter is using const for, more or less.
- A threadsafe function need not be const. (Clearly.)
- A function that doesn't change anything that anyone can see need not
be threadsafe (caching, logfiles, everything everyone has posted in the
past three days).
More information about the Digitalmars-d
mailing list