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.

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???

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.

So the only way to make your proposal work would be to forbid all functions from taking `shared T*` or `ref shared T` argument. Except we can't do that, because a method is just a function with an implicit first argument. The code above is the same as this:

void foo(ref shared S, shared Other*);

It's literally *the same signature*. So there's nothing in the language to prevent calling that on an unshared S either.

To sum up, things you implied but never specified in your proposal:

1. Primitive types can't be explicitly `shared`.
2. Free functions taking `shared` arguments are not allowed.
3. Only `shared` methods can implement threadsafe operations on `shared` data (which contradicts (2) already) <- this one you did specify. 4. Every variable is implicitly shared, whether intended so or not.

Reply via email to