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