April 11, 2023

On Tuesday, 11 April 2023 at 17:30:34 UTC, Hipreme wrote:

>

pure breaks logging in your function for debugging

You can use a debug statement for that, which looks like debug writeln("log");. Or, what I do, create a 'debug print' function that looks like something this:

void dprint(T...)(auto ref T args, int line = __LINE__, string file = __FILE__)
{
    debug writeln(file, "(", line, "): ", args);
}
April 11, 2023
On 4/11/2023 10:30 AM, Hipreme wrote:
> `pure` breaks logging in your function for debugging,

That's why the following works:

pure void foo()
{
    debug printf("inside foo()\n");
}


> `const` you need to specify it everywhere or else your thing won't compile. This is a great friction I get which I took the decision to just drop those.

True, you can just not use const.
April 11, 2023
Consider the following:

    shared int* p;

With transitive shared, that makes p and *p both shared. If I'm understanding your post, you propose changing things so p is shared and *p is not shared.

The issue with that is *p loses what thread it belongs to, and will then (to be thread safe) have to be synchronized.

I agree it is likely easier to write programs this way, but I suspect it will be a lot harder to write correct programs, and the compiler will be unable to help with that.

I have thought about head const (aka final) many times, but didn't come to any conclusions.
April 12, 2023
On Wednesday, 12 April 2023 at 05:10:36 UTC, Walter Bright wrote:
> Consider the following:
>
>     shared int* p;
>
> With transitive shared, that makes p and *p both shared. If I'm understanding your post, you propose changing things so p is shared and *p is not shared.
>
> The issue with that is *p loses what thread it belongs to, and will then (to be thread safe) have to be synchronized.
>
> I agree it is likely easier to write programs this way, but I suspect it will be a lot harder to write correct programs, and the compiler will be unable to help with that.
>

Humanity has been writing concurrent programs even without explicit shallow shared for decades now. Together with explicit head-shared we are strictly better than status quo.


> I have thought about head const (aka final) many times, but didn't come to any conclusions.


April 11, 2023
On 4/11/2023 10:36 PM, Dmitry Olshansky wrote:
> Humanity has been writing concurrent programs even without explicit shallow shared for decades now.

Of course you're right. And suffered endless weird and hard to debug problems.


> Together with explicit head-shared we are strictly better than status quo.

Are we in terms of safety and correctness?
April 12, 2023
> Templates without extreme precautions and Unqual!T all around will get instantiated up to 3x(!) times.

I'm not sure why `Unqual!T` exists. `cast()T` will remove all the head qualifiers, no templates involved.
April 12, 2023
On 12/04/2023 6:42 PM, Walter Bright wrote:
>> Together with explicit head-shared we are strictly better than status quo.
> 
> Are we in terms of safety and correctness?

I remain sincerely unconvinced.

Shared is the exact opposite of what is needed.

Unless proven otherwise, all memory is owned by the process not the thread and therefore is the default.

The only way I've been able to use it successfully is to treat it as if it was `atomic`. Only without any of the QoL stuff that `atomic` could bring.
April 12, 2023
On 4/12/2023 12:11 AM, Richard (Rikki) Andrew Cattermole wrote:
> Unless proven otherwise, all memory is owned by the process not the thread and therefore is the default.

Let's see if I understand:

    int abc(int* p);

    int sum(int[] a)
    {
        int sum = 0;
        abc(&sum);
        for (int i = 0; i < a.length; ++i)
            sum += a[i];
        return sum;
    }

Your position is that `i` and `sum` should be shared variables? What if `abc(&sum)` passes `&sum` to a concurrent thread?
April 12, 2023
On 4/12/2023 12:05 AM, Walter Bright wrote:
>  > Templates without extreme precautions and Unqual!T all around will get instantiated up to 3x(!) times.
> 
> I'm not sure why `Unqual!T` exists. `cast()T` will remove all the head qualifiers, no templates involved.

Oops. That is, cast()E will remove all the qualifiers from the type of E. So Unqual!T needs to exist. My mistake.
April 12, 2023
On 12/04/2023 7:27 PM, Walter Bright wrote:
> On 4/12/2023 12:11 AM, Richard (Rikki) Andrew Cattermole wrote:
>> Unless proven otherwise, all memory is owned by the process not the thread and therefore is the default.
> 
> Let's see if I understand:
> 
>      int abc(int* p);
> 
>      int sum(int[] a)
>      {
>          int sum = 0;
>          abc(&sum);
>          for (int i = 0; i < a.length; ++i)
>              sum += a[i];
>          return sum;
>      }
> 
> Your position is that `i` and `sum` should be shared variables? What if `abc(&sum)` passes `&sum` to a concurrent thread?

No, you have that backwards.

In both of those cases its owned by the thread. With @safe they would be scope, which is a partial implementation of 'owned by thread' checking.

A better example would be `a`. This is an argument, with an unknown memory lifetime or ownership, that should be shared implicitly even if it was marked scope.