shared - i need it to be useful

Simen Kjærås simen.kjaras at gmail.com
Thu Oct 18 11:35:21 UTC 2018


On Thursday, 18 October 2018 at 10:08:48 UTC, Stanislav Blinov 
wrote:
> Manu,
>
> how is it that you can't see what *your own* proposal means??? 
> Implicit casting from mutable to shared means that everything 
> is shared by default! Precisely the opposite of what D 
> proclaims.

Well, sorta. But that's not a problem, because you can't do 
anything that's not threadsafe to something that's shared.


> You also essentially forbid defining *any* functions that take 
> `shared T*` argument(s). You keep asking for concrete "holes". 
> Don't you see what the previous "atomicInc" example implies???

I certainly don't. Please do elucidate.


> If *any* free function `foo(shared T* bar)`, per your 
> definition, is not threadsafe, then no other function with 
> shared argument(s) can be threadsafe at all. So how do you call 
> functions on shared data then? You keep saying "methods, 
> methods..."
>
> struct Other { /* ... */ }
>
> struct S {
>     void foo(shared Other*) shared;
> }
>
> Per your rules, there would be *nothing* in the language to 
> prevent calling S.foo with an unshared Other.

That's true. And you can't do anything to it, so that's fine.


> So the only way to make your proposal work would be to forbid 
> all functions from taking `shared T*` or `ref shared T` 
> argument.

No. Please read this thread again. From the beginning, every 
word. Actually, don't do that, because Manu's proposal is simple 
and elegant:

> 1. the rule must be applied that shared object can not be read 
> or written
> 2. attributing a method shared is a statement and a promise 
> that the
> method is threadsafe
> 
> The rest just follows naturally.

There's actually one more thing: The one and only thing you can 
do (without unsafe casting) with a shared object, is call shared 
methods and free functions on it.


> To sum up, things you implied but never specified in your 
> proposal:
>
> 1. Primitive types can't be explicitly `shared`.

Sure they can, they just can't present a thread-safe interface, 
so you can't do anything with a shared(int).


> 2. Free functions taking `shared` arguments are not allowed.

Yes, they are. They would be using other shared methods or free 
functions on the shared argument, and would thus be thread-safe. 
If defined in the same module as the type on which they operate, 
they would have access to the internal state of the object, and 
would have to be written in such a way as to not violate the 
thread-safety of other methods and free functions that operate on 
it.


> 3. Only `shared` methods can implement threadsafe operations on 
> `shared` data (which contradicts (2) already) <- this one you 
> did specify.

Non-shared methods are perfectly free to be thread-safe (and they 
should be, in the sense that they shouldn't interfere with shared 
methods). A better way to state this is that only shared methods 
may be called on a shared object. A shared object may also be 
passed to a function taking a shared parameter.


> 4. Every variable is implicitly shared, whether intended so or 
> not.

Well, yes, in the same sense that every variable is also 
implicitly const, whether intended so or not.

--
   Simen


More information about the Digitalmars-d mailing list