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

Reply via email to