<div dir="ltr"><div dir="ltr">On Wed, Aug 5, 2020 at 3:20 AM Timon Gehr via Digitalmars-d <<a href="mailto:digitalmars-d@puremagic.com">digitalmars-d@puremagic.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 04.08.20 04:13, Andrei Alexandrescu wrote:<br>
> On 8/3/20 5:56 PM, Manu wrote:<br>
>> I think shared has potential to offer critical benefit to D, and we've <br>
>> talked about this personally to some length. Don't kill it yet, let's <br>
>> try and fix it. Although it's worth recognising that if we don't fix <br>
>> it, then it might as well be killed as it stands today.<br>
> <br>
> Of course fixing it would be great!<br>
<br>
It's being fixed, but Manu's vision for "fixing" it is really to do more <br>
than fixing it.  Manu thinks "unshared" is useless as a type qualifier.<br>
<br>
He wants to change the meaning of `shared` so it no longer means <br>
"shared", but instead means "thread safe".</blockquote><div><br></div><div>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.</div><div>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.</div><div><br></div><div>This would be immensely useful to enable various parallel workloads, parallel-for is a key target.<br></div><div>The trouble is, and I think you pointed it out before, when multiple arguments alias eachother:<br></div><div><br></div><div>void fun(ref X a, ref scope shared(X) b) { /* a and b are a shared + unshared alias... */ }<br><br>X x;<br>fun(x, x);</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> For plain variables, this <br>
"thread safe" annotation would also imply "shared" (in an unprincipled <br>
manner, breaking the type system).<br>
<br>
"thread safe" is to "shared" approximately as "const" is to "mutable". <br>
That's also why all variables can implicitly convert to "thread safe".<br>
<br>
> I'm glad you pushed the restriction <br>
> through. At least now generic code could see `shared` as "shrouded in <br>
> opacity, not subject to the usual operations".<br>
<br>
Luckily the restriction makes sense for `shared` even if its meaning is <br>
not changed to be different from its name.<br></blockquote><div><br></div><div>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.</div></div></div>