Struggling to implement parallel foreach...

Timon Gehr timon.gehr at gmx.ch
Fri Jun 14 12:02:00 UTC 2019


On 14.06.19 07:51, Manu wrote:
> On Thu, Jun 13, 2019 at 7:00 PM Timon Gehr via Digitalmars-d
> <digitalmars-d at puremagic.com> wrote:
>>
>> On 14.06.19 03:40, Manu wrote:
>>> void test()
>>> {
>>>           int x;
>>>           void fun() shared
>>>           {
>>>               x++; // <-- error here
>>>           }
>>>           fun();
>>> }
>>>
>>> And I got this error:
>>>
>>> Error: `shared` function `test.fun` cannot access non-shared data `x`
>>>
>>> That looks like a bug.
>>
>> It's by design. It's not pretty that the qualifiers have a different
>> meaning for member functions and nested functions (because the nested
>> function meaning could be useful for member functions too), but it's
>> what we have.
> 
> Okay. Well, that seems like bad design. Why is it that way? How do we fix this?
> I've been working towards parallel foreach for like 18 months here, I
> finally have all my ducks in a line, try and type the thing, and it
> doesn't work...
> ...

The simplified example above should definitely not compile, and the 
error message is fine. Your parallel `foreach` should certainly work, 
and the compiler needs to be fixed to support it. I don't see however 
what one has to do with the other.

>>> `fun` is a delegate, and it's shared, which
>>> means its `this` pointer is shared, which means `this.x` should be
>>> shared... but that seems not to be the case.
>>> ...
>>
>> There is no `this` pointer.
> 
> What do you mean? Local functions receive a context just like any
> method... if it's attributed, then it should be attributed.
> ...

There is no such thing. This makes no sense. You can't "attribute a 
context".

>> For local functions, `shared` means that
>> every variable accessed in the context is shared.
> 
> Not clear what you mean. It sounds like you suggest what I expect, but
> that's not what I observe.
> I expect that if the context is shared, then the transitive rule
> applies normal. Everything accessed should be shared...?
> ...

That doesn't mean it is implicitly made shared, it has to be shared to 
begin with.

>>> I think this is a bug. The compile error should have been that I was
>>> unable to call fun() with a non-shared delegate (since the calling
>>> scope is not shared).
>>
>> There is no way to make the "calling scope shared".
> 
> Yes. So I expect the compile error I suggested?
> 

That error makes no sense. Your problem is that local functions don't 
infer context qualifiers. E.g.:

void main(){
     pragma(msg, typeof(delegate(){})); // should be: void delegate() 
immutable pure nothrow @nogc @safe
}

Currently, `immutable` is not included.

This should certainly be fixed. Even if there is not full inference, 
this should certainly work:

void foo(void delegate()shared dg){}
void main(){ foo((){}); }




More information about the Digitalmars-d mailing list