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