<div dir="ltr"><div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon., 17 Jun. 2019, 11:40 am Timon Gehr via Digitalmars-d, <<a href="mailto:digitalmars-d@puremagic.com" target="_blank">digitalmars-d@puremagic.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 17.06.19 03:17, Manu wrote:<br>
> On Sun, Jun 16, 2019 at 6:00 PM Kagamin via Digitalmars-d<br>
> <<a href="mailto:digitalmars-d@puremagic.com" rel="noreferrer" target="_blank">digitalmars-d@puremagic.com</a>> wrote:<br>
>><br>
>> On Saturday, 15 June 2019 at 06:13:09 UTC, Manu wrote:<br>
>>> struct S<br>
>>> {<br>
>>>    void method() shared;<br>
>>> }<br>
>>><br>
>>> void test()<br>
>>> {<br>
>>>    S s;<br>
>>>    void localFun() shared<br>
>>>    {<br>
>>>      s.method(); // <- s must transitively receive const from the<br>
>>> context pointer, otherwise this doesn't work<br>
>>>    }<br>
>>> }<br>
>>><br>
>>> Current semantics would reject this, because s is not shared,<br>
>>> and<br>
>>> therefore not accessible by localFun.<br>
>>> The unnecessary complexity inhibits the only useful thing that a<br>
>>> shared function can do.<br>
>><br>
>> Declare `s` as shared and it will work. It would receive<br>
>> qualifier from context, but unshared variables can't be captured<br>
>> by shared closure to begin with because unshared data can't part<br>
>> of shared context, because that would break the guarantee that<br>
>> unshared data shouldn't be shared. Currently compiler implements<br>
>> check which variables can be captured and which can't.<br>
> <br>
> I don't think the capture should be shared, only the function argument<br>
> has the shared attribute applied, ie:<br>
> Capture cap;<br>
> void localFun(shared(Capture)* ctx);<br>
> localFun(cap); // <- error: can't pass `Context*` to<br>
> `shared(Context)*`... form there, we can begin to do something<br>
> interesting.<br>
> <br>
> In you consider the const case, this will work perfectly fine, and<br>
> everything will be as expected with absolutely no magic of any kind.<br>
> immutable local functions can not be called under any circumstances;<br>
> this seems like common sense to me.<br>
<br>
It's not common sense, it's nonsense. It should be common sense that it <br>
is nonsense. I don't understand how you can possibly reach that <br>
conclusion. Closures with an immutable-qualified context can only <br>
capture immutable variables. What is so surprising about this?<br></blockquote><div><br></div><div>What's the use of that? Can you point me at any code like that?</div><div>Make a const local function if you want to stop it mutating stuff... what's interesting about an immutable local function?<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> inout is fine too, just like const.<br>
<br>
Absolutely not. You can't implicitly promote stuff to `inout`.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">What are you taking about? inout accepts mutable, const, or immutable. I don't know what you could mean?</div><div dir="auto">Context objects are mutable, unless called via another local function where they would have gained the respective qualifier, and that would interact with inout correctly, eliminating some existing false-mutability bugs.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> shared is the interesting one; we shouldn't be able to pass the<br>
> capture to the function because Context* -> shared(Context)*, but we<br>
> can start to talk about ways this can work.<br>
> One way is that the promotion is actally perfectly valid! Because you<br>
> are calling a local function from the local thread; so the shared<br>
> function will have a shared reference to the local context only for<br>
> the life of the function call, and when it returns, the shared<br>
> reference must end with the function. We can do this by declaring the<br>
> local function: `void localFun(scope shared(Context)* ctx);`<br>
> A shared local function is valid so long as that function does NOT<br>
> escape any of those shared references. It might want to attribute<br>
> `return` too.<br>
<br>
This idea is not at all contingent on the nonsensical</blockquote><div><br></div><div>How is uniformity nonsense? Are you saying that qualified methods are nonsense? How could applying proven, uniform, and predictable rules be considered nonsense?</div><div>Can you show me how these special-case rules are useful? Qualified local functions are extremely rare; I suspect someone just dun some design that sounded cool and felt chuffed, but probably never used it.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">parts of your <br>
vision, but I don't know if there is a simple way to make this work. It <br>
will require more care.<br></blockquote><div><br></div><div>I agree there's certainly no simple way to do it assuming the current design; I did try and imagine a solution extensively under the existing implementation for quite some time, but I don't believe it's possible without effectively transforming it towards the default semantics.</div><div>...which isn't actually surprising! You shouldn't be surprised that uniform semantics interact properly with all the other existing language. If the design just worked like any normal qualified this pointer, there'd be nothing to think about other than how to call the shared function, which I think is a problem we can defeat. Everything else would work elegantly with no special code in the compiler.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
>>From there, parallel foreach can be implemented as a @trusted function.<br>
> <br>
<br>
So your evil master plan is:<br>
<br>
1. Make qualified local functions useless.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Not at all, const and inout work as expected (surely the 99% case), and reflective meta will actually work too. Existing bugs are all eliminated instantly. `immutable` has no useful meaning anyway (just use const? The thing about local functions is that they're local. It's not API material), shared is the only interesting case that's affected, and I can't imagine another way to make it useful.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
2. Make qualified local functions more useful.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">If you can do this without 1, then great. I couldn't imagine a solution. The problem is specifically the non-uniformity and special case rules.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
3. Profit.<br>
<br>
Just skip phase 1, please.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">I've asked a couple of times for a demonstration of how existing semantics are useful? It's certainly complex, non-uniform, and surprising.</div><div dir="auto">The closure has un-qualified objects in it despite the function qualification, which means typeof() doesn't work right, and derivative meta that depends on that is broken by consequence.</div><div dir="auto"><br></div><div dir="auto">Explain to me how qualifying the context makes it useless? How does it make anything that works right now stop working?</div><div dir="auto">I think that makes it uniform, only meaningfully affects shared (in a positive way), and removes a mountain of complex special case code.</div><div dir="auto"><br></div><div dir="auto">But you know what, do what you want, I'll shut up... If it just gets fixed, I won't complain.</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
</blockquote></div></div></div>
</div>