April 02, 2018
On 02.04.2018 10:04, Shachar Shemesh wrote:
> On 02/04/18 10:45, Jonathan M Davis wrote:
>> Honestly, I think at this point pure is easier to understand if you think of
>> it as @noglobal and don't think about functional purity at all.
> 
> That's fine. My point was that the only optimizations possible are possible on strictly pure functions (the immutable cast one included). Weakly pure functions add nothing.
> ...

That point is wrong. It would be wrong even if your next point was true.

> But merely having them around means that when I annotate a function with "pure", I do not promise any guarantees that the compiler can actually use to perform optimizations.
> 
> Shachar

Yes, actually you do.

For example, if you have:

void foo(int[] x)pure;

void main(){
    auto x = [1];
    auto y = x.dup;
    foo(x);
    foo(y);
}

This can be transformed into:

void main(){
    auto x = [1];
    foo(x);
    auto y = x.dup;
}

Pure functions have deterministic side-effects.
April 02, 2018
On Sunday, 1 April 2018 at 11:17:38 UTC, Patrick Schluter wrote:

>> What I was wondering too. I mean, breaking changes just don't happen to this language. Now there will be, without even an indication of how existing code would have to be rewritten, or how this large-scale breakage is different than the breakages that just can't happen because reasons. I guess that's why there's always the disclaimer, "We'll only break code if there's a really good reason." That reason is "in case we want to".
>
> Nothing has been lay out yet and people are already freaking out. No wonder nothing gets done anymore.

No, the reason nothing gets done is because "that would break code" is used to kill every proposal that comes along. Someone that only responds to proposals with "write a DIP" proceeds to announce a major piece of the language will be deprecated without writing a DIP himself. Corporate leadership doesn't work with an open source project. I could have gotten more involved long ago, but I'd rather not jump on a ship that's sailing in circles. From the many comments I've seen, I'm not the only one.
April 02, 2018
On Sunday, 1 April 2018 at 14:31:24 UTC, Andrei Alexandrescu wrote:
> 1. For immutable objects, typechecking in the presence of successive modifications of data (first assignment by the compiler, then modification by the user) is very difficult if not impossible. I don't know how to do it. The single initialization model (raw/cooked) used currently in regular immutable constructors works reasonably well and is robust.

Do the same as in const constructor.

> 2. For shared objects, the part done by the compiler and the part done by this(this) should be synchronized together. This makes it impossible for the user to e.g. define a struct that gets copied atomically.

If you mean reference counting, the easy solution with copy constructor is bad performance wise. Good solution can be done architecturally now and doesn't rely on copy constructor.
April 02, 2018
On 4/1/18 10:34 AM, ag0aep6g wrote:
> On Sunday, 1 April 2018 at 13:37:43 UTC, Jonathan M Davis wrote:
>> One issue is that postblit constructors fundamentally don't work with const. The problem is that a postblit constructor works by copying the object and _then_ mutating it, and you can't mutate a const object.
> 
> I'm not so sure if that's fundamental. Can't we just say that the copy is head-mutable at the time when the postblit function is called, and it only becomes fully const after that?
> 
> The destination can't be const/immutable already, or you wouldn't be able to write there anyway.

Yes, precisely what I had been arguing here: https://issues.dlang.org/show_bug.cgi?id=18417#c5, however const/immutable postblit was recently deprecated by: https://github.com/dlang/dmd/pull/8032

So I don't think D is going to allow const postblit any more. Maybe not even postblit any more.

-Steve
April 02, 2018
On Sunday, 1 April 2018 at 14:31:24 UTC, Andrei Alexandrescu wrote:
> There's a mix of fundamental flaws and bugs. I'll get to the flaws in a second. About the bugs: people have altered their code in various ways to work with the bizarre semantics of this(this). Now, if we fix various bugs in this(this) by virtually redefining it, then we'll break a lot of code in a lot of ways. To wit, we fixed a small issue and it already created problems: https://github.com/dlang/dmd/pull/8032. That didn't contribute to the decision but is quite illustrative.

Since poorly thought decisions keep being made for the language it's doubtful that "no breakage" policy has real backing.
April 02, 2018
On Monday, 2 April 2018 at 14:07:21 UTC, Steven Schveighoffer wrote:
> On 4/1/18 10:34 AM, ag0aep6g wrote:
>> On Sunday, 1 April 2018 at 13:37:43 UTC, Jonathan M Davis wrote:
>>> One issue is that postblit constructors fundamentally don't work with const. The problem is that a postblit constructor works by copying the object and _then_ mutating it, and you can't mutate a const object.
>> 
>> I'm not so sure if that's fundamental. Can't we just say that the copy is head-mutable at the time when the postblit function is called, and it only becomes fully const after that?
>> 
>> The destination can't be const/immutable already, or you wouldn't be able to write there anyway.
>
> Yes, precisely what I had been arguing here: https://issues.dlang.org/show_bug.cgi?id=18417#c5, however const/immutable postblit was recently deprecated by: https://github.com/dlang/dmd/pull/8032
>
> So I don't think D is going to allow const postblit any more. Maybe not even postblit any more.
>
> -Steve

Andrei did post an example where treating the designation as mutable, stuffing references to mutable data into is and then treating it as immutable leaves you with an immutable reference to immutable data.

However i think that loophole is fixed if you only allow assignment to const/immutable from a pure postblit.

April 02, 2018
On Monday, 2 April 2018 at 14:01:22 UTC, Kagamin wrote:
> On Sunday, 1 April 2018 at 14:31:24 UTC, Andrei Alexandrescu wrote:
>> 1. For immutable objects, typechecking in the presence of successive modifications of data (first assignment by the compiler, then modification by the user) is very difficult if not impossible. I don't know how to do it. The single initialization model (raw/cooked) used currently in regular immutable constructors works reasonably well and is robust.
>
> Do the same as in const constructor.

The way it works in a const constructor is that `this.foo = bar;` is considered initialization, not assignment.

In a postblit function, we can't say it's initialization, because the field already has a value that can't be ignored.
April 02, 2018
On 4/2/18 10:24 AM, Nicholas Wilson wrote:
> On Monday, 2 April 2018 at 14:07:21 UTC, Steven Schveighoffer wrote:
>> On 4/1/18 10:34 AM, ag0aep6g wrote:
>>> On Sunday, 1 April 2018 at 13:37:43 UTC, Jonathan M Davis wrote:
>>>> One issue is that postblit constructors fundamentally don't work with const. The problem is that a postblit constructor works by copying the object and _then_ mutating it, and you can't mutate a const object.
>>>
>>> I'm not so sure if that's fundamental. Can't we just say that the copy is head-mutable at the time when the postblit function is called, and it only becomes fully const after that?
>>>
>>> The destination can't be const/immutable already, or you wouldn't be able to write there anyway.
>>
>> Yes, precisely what I had been arguing here: https://issues.dlang.org/show_bug.cgi?id=18417#c5, however const/immutable postblit was recently deprecated by: https://github.com/dlang/dmd/pull/8032
>>
>> So I don't think D is going to allow const postblit any more. Maybe not even postblit any more.
>>
> 
> Andrei did post an example where treating the designation as mutable, stuffing references to mutable data into is and then treating it as immutable leaves you with an immutable reference to immutable data.

I think you meant immutable reference to mutable data.

> 
> However i think that loophole is fixed if you only allow assignment to const/immutable from a pure postblit.
> 

It's pretty straightforward I would think: If a postblit is being called on an immutable, it *must* be new data, because if it was data that just got overwritten, that data couldn't possibly be immutable. Therefore, there's leeway to mutate the head at that point, because nothing else can see it yet. Doesn't need to be pure.

Same leeway as an immutable constructor I think.

But all this discussion is moot if the postblit is going away.

-Steve
April 02, 2018
On Monday, 2 April 2018 at 14:24:20 UTC, Nicholas Wilson wrote:
> On Monday, 2 April 2018 at 14:07:21 UTC, Steven Schveighoffer wrote:
>> On 4/1/18 10:34 AM, ag0aep6g wrote:
[...]
>>> I'm not so sure if that's fundamental. Can't we just say that the copy is head-mutable at the time when the postblit function is called, and it only becomes fully const after that?
[...]
>> Yes, precisely what I had been arguing here: https://issues.dlang.org/show_bug.cgi?id=18417#c5
[...]
> Andrei did post an example where treating the designation as mutable, stuffing references to mutable data into is and then treating it as immutable leaves you with an immutable reference to immutable data.

This one?

----
int[] sneaky;
struct A
{
    private int[] innocent;
    this(this)
    {
        sneaky = innocent;
    }
}
void main()
{
    immutable a = A([1, 2, 3]);
    auto b = a;
    sneaky[1] = 42; // oops
    import std.stdio;
    writeln(a.innocent); // ooooops
}
----

That wouldn't be possible if `innocent` were only head-mutable in the postblit function, instead of fully mutable as it is currently (bug).

`innocent` would be typed as `immutable(int)[]`, and you could not assign it to the fully mutable `sneaky`.

> However i think that loophole is fixed if you only allow assignment to const/immutable from a pure postblit.

Still must be head-mutable only. With fully mutable, you can mutate data that is seen as immutable elsewehre, even if the postblit function is pure:

----
struct S
{
    int* x;
    this(this) pure { *x = 13; }
}
void main()
{
    auto s = immutable S(new int(42));
    auto s2 = s;
    assert(*s.x == 42); /* fails; immutability has been broken */
}
----

Issue 18357 covers both Andrei's example, and this one.
https://issues.dlang.org/show_bug.cgi?id=18357
April 02, 2018
On Monday, 2 April 2018 at 13:55:25 UTC, bachmeier wrote:

> No, the reason nothing gets done is because "that would break code" is used to kill every proposal that comes along. Someone that only responds to proposals with "write a DIP" proceeds to announce a major piece of the language will be deprecated without writing a DIP himself. Corporate leadership doesn't work with an open source project. I could have gotten more involved long ago, but I'd rather not jump on a ship that's sailing in circles. From the many comments I've seen, I'm not the only one.

Andrei wrote in the message

>I am looking for folks to assist me in creating a DIP for that.
>There will be a _lot_ of work involved, so don't take it lightly.

So, let's keep the discussion factual. I'm pretty sure that every aspect will be taken in account and pondered prior to a decision.

I'm +1 on major breaking changes if they drive D towards a better shape.

/Paolo