Generality creep

FeepingCreature feepingcreature at gmail.com
Fri Apr 5 09:28:06 UTC 2019


On Thursday, 4 April 2019 at 21:05:51 UTC, Walter Bright wrote:
> On the plus side of shared as it is at the moment, and it's a 
> pretty big plus, is it identifies what data is shared, and how 
> it's integrated into the type system is good.
>
> With C and C++, when you've got a shared memory bug, you have 
> no idea where to start. In D, you look at the shared stuff. 
> You're not going to have inadvertently shared variables.

I mean, given that synchronized classes don't strip out the first 
layer of shared, as is necessary to make them, basically, *at 
all* usable, we're currently forced to use synchronized(this) ... 
which does not force shared at all. So this seems optimistic.

Thinking more about it, I feel shared is a fundamentally wrong 
direction. Even stripping out the first layer, I'll not be able 
to naturally read or modify anything with references, say an int 
array, because the language can't know that nothing else has a 
view on the array. I'd be limited to arrays of immutable data, 
with all the "can never overwrite a field, even though I own the 
array" problems that brings.

Istm that the more natural way to use shared in the context of 
classes would be to talk not in terms of whether data is shared 
or not, but whether data is *owned* by the class. If I 
transitively owned the array in a synchronized class, I could 
overwrite what I want at will, confident that any access would be 
happening behind a synchronized block.

ie.

struct S
{
   int[] data; // reference
}

synchronized class S
{
   private owned S[] array;

   // valid despite shared - array is not shared, because we own 
it.
   void test1(size_t index) { array[index] = owned(S)(null); }

   // not valid - `data` references caller data; we can't take 
ownership of it.
   void test2(int[] data) { array[index] = owned(S)(data); }

   // valid - we have exclusive ownership on data.dup
   void test3(int[] data) { array[index] = owned(S)(data.dup); }

   // invalid - can't escape owned data.
   owned(S) test4() { return array.front; }

   // valid
   S test5() { return S(array.front.data.dup); }
}

As far as I can see, in production use synchronization is about 
atomic access only in the very rarest of cases. I can't imagine 
why a domain class would ever return anything shared (who would 
trust the outside world to know how to correctly access it?), and 
inside class methods, presuming we own our data, as classes 
*should anyways*, shared has no benefit because there's only one 
reader/writer anyways. In comparison, imo, owned would formalize 
the way that threadsafe classes should be written *anyways*.



More information about the Digitalmars-d mailing list