I wish all qualifiers were revisited with an eye for simplification

Manu turkeyman at gmail.com
Wed Aug 5 03:53:20 UTC 2020


On Wed, Aug 5, 2020 at 3:20 AM Timon Gehr via Digitalmars-d <
digitalmars-d at puremagic.com> wrote:

> On 04.08.20 04:13, Andrei Alexandrescu wrote:
> > On 8/3/20 5:56 PM, Manu wrote:
> >> I think shared has potential to offer critical benefit to D, and we've
> >> talked about this personally to some length. Don't kill it yet, let's
> >> try and fix it. Although it's worth recognising that if we don't fix
> >> it, then it might as well be killed as it stands today.
> >
> > Of course fixing it would be great!
>
> It's being fixed, but Manu's vision for "fixing" it is really to do more
> than fixing it.  Manu thinks "unshared" is useless as a type qualifier.
>
> He wants to change the meaning of `shared` so it no longer means
> "shared", but instead means "thread safe".


This's a highly speculative end-goal, but a lot of my work applies to
'shared' equally with respect to today's definition, and also that
potential definition.
Leaving the 'thread-safe' definition aside, the key goal I want to achieve
is that you may perform an implicit conversion to `scope shared`; since it
can't escape the callee and therefore no references should co-exist with
the thread-local instance in the calling scope.

This would be immensely useful to enable various parallel workloads,
parallel-for is a key target.
The trouble is, and I think you pointed it out before, when multiple
arguments alias eachother:

void fun(ref X a, ref scope shared(X) b) { /* a and b are a shared +
unshared alias... */ }

X x;
fun(x, x);

Allowing implicit conversion to `scope shared` requires that the caller and
callee's scopes are a clear division between the unshared and the
promoted-to-shared instances. scope enforces that we can't escape the
callee's promoted-to-shared ref to alias the unshared ref in the callers
scope, but that division can be violated by aliasing the caller's
reference, and sneaking an unshared reference into the callee beside the
promoted reference.

That problem makes the implicit conversion in the presence of scope
challenging, and that is what leads to the design where `shared` comes to
mean 'thread-safe' instead of simply shared; which insists a stronger set
of requirements, and under that changed definition, it allows the alias to
exist.

If there was another way to prevent the caller's unshared ref from aliasing
its way into the callee, that would be preferable to the scheme I described
before.

For plain variables, this
> "thread safe" annotation would also imply "shared" (in an unprincipled
> manner, breaking the type system).
>
> "thread safe" is to "shared" approximately as "const" is to "mutable".
> That's also why all variables can implicitly convert to "thread safe".
>
> > I'm glad you pushed the restriction
> > through. At least now generic code could see `shared` as "shrouded in
> > opacity, not subject to the usual operations".
>
> Luckily the restriction makes sense for `shared` even if its meaning is
> not changed to be different from its name.
>

It's not really 'lucky', it's fundamental to any conceivable definition of
shared. It's a starting point that's actually possible to work out from.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20200805/3b40b80e/attachment.htm>


More information about the Digitalmars-d mailing list