April 15, 2016
On Friday, 15 April 2016 at 05:38:56 UTC, Andrei Alexandrescu wrote:
>
> I think we should deprecate inout. For real. It costs way too much for what it does. For all I can tell most of D's proponents don't know how it works. -- Andrei

This is the explanation I came up with, not sure if accurate. And only to teach myself the basics.
https://p0nce.github.io/d-idioms/#Knowing-inout-inside-out

I'm all for removing things!

April 15, 2016
On 15.04.2016 05:10, Andrei Alexandrescu wrote:
> Consider:
>
> https://github.com/D-Programming-Language/phobos/blob/master/std/range/primitives.d#L152
> ...


Related: Phobos should never use is(typeof(...)). Contrary to popular belief, is(typeof(...)) is not the same as __traits(compiles,...).

void main(){
    int x;
    static void foo(){
        static assert(is(typeof({return x;})));
        static assert(!__traits(compiles,{return x;}));
    }
}


typeof suspends context access checks. This is almost never what you want when checking for compilability.

>
> There is no explanation to it in the source code, and the line blames to
> https://github.com/D-Programming-Language/phobos/pull/2661 (irrelevant).
>
> Commenting it out yields a number of unittest compilation errors,
> neither informative about the root of the problem and indicative as to
> how the parameter solves it.
>
> There are two issues here:
>
> 1. Once a problem/solution pair of this degree of subtlety crops up, we
> need to convince ourselves that that's sensible. If we deem it not so,
> we look into improving the language to make the problem disappear.
> ...

Declaring variables with inout in their type is only allowed for stack variables in functions that have inout parameters. The (inout int) trick attempts to allow such types to be ranges.

It is not even a correct fix: Most of Phobos code assumes that ranges be struct fields. The following code causes a compilation failure in the guts of std.algorithm:

inout(int)[] foo(inout(int)[] x){
    static assert(isInputRange!(typeof(x)));
    return x.map!(x=>x).array;
}


What good is an "InputRange" that does not support map?


The fundamental problem is that inout is disallows certain kinds of composition. It's a flawed language primitive. The way to fix this is to have parametric polymorphism in the language.
April 15, 2016
On 15.04.2016 11:07, Timon Gehr wrote:
> ... Most of Phobos code assumes that ranges be struct fields.

Most of Phobos assumes that ranges can be

>
> The fundamental problem is that inout is disallows certain kinds of
> composition. ...

inout disallows

April 15, 2016
2016-04-15 14:38 GMT+09:00 Andrei Alexandrescu via Digitalmars-d < digitalmars-d@puremagic.com>:

> On 04/15/2016 12:23 AM, Jonathan M Davis via Digitalmars-d wrote:
>
>> On Thursday, April 14, 2016 23:10:12 Andrei Alexandrescu via Digitalmars-d wrote:
>>
>>> Consider:
>>>
>>>
>>> https://github.com/D-Programming-Language/phobos/blob/master/std/range/primi tives.d#L152
>>>
>>> There is no explanation to it in the source code, and the line blames to https://github.com/D-Programming-Language/phobos/pull/2661 (irrelevant).
>>>
>>> Commenting it out yields a number of unittest compilation errors, neither informative about the root of the problem and indicative as to how the parameter solves it.
>>>
>>> There are two issues here:
>>>
>>> 1. Once a problem/solution pair of this degree of subtlety crops up, we need to convince ourselves that that's sensible. If we deem it not so, we look into improving the language to make the problem disappear.
>>>
>>> 2. There needs to be documentation for people working on the standard library so they don't need to waste time on their own discovery process.
>>>
>>> We want Phobos to be beautiful, a prime example of good D code. Admittedly, it also needs to be very general and efficient, which sometimes gets in the way. But we cannot afford an accumulation of mad tricks to obscure the large design.
>>>
>>
>> IIRC, the problem has to do with ranges of inout elements working
>> correctly,
>> which gets really funky, because inout is a temporary thing and not a
>> full-on type constructor/qualifier. I believe that Kenji is the one that
>> implemented the fix, and I think that he explained it in the newsgroup at
>> some point. Certainly, there have been a few times that it's come up in
>> D.Learn when folks ask what the heck it is, so there should be a few posts
>> floating around with an explanation. This is the only useful post that I
>> could find in a quick search though:
>>
>> http://forum.dlang.org/post/mh68p8$2p56$1@digitalmars.com
>>
>> inout attempts to solve a very real problem, but it does seem to be
>> surprisingly hard to understand and use prooperly even though it's
>> theoretically simple. And this bit with ranges is a quirk that I think
>> very
>> few people understand and remember. I usually forget exactly what it does
>> when it comes up and have to try and dig through the newsgroup archives
>> for
>> a previous discussion on it.
>>
>> - Jonathan M Davis
>>
>
> I think we should deprecate inout. For real. It costs way too much for what it does. For all I can tell most of D's proponents don't know how it works. -- Andrei
>


You should recall the history of inout. http://wiki.dlang.org/DIP2

At first, It has designed to temporarily squash mutable/const/immutable qualifiers on function argument inside function body. Therefore when inout qualifier appears in function return type, but doesn't on parameter types, we defined it an error.

However, I concluded that we can remove the restriction. When an inout object arises from thin air, no one holds the qualifier of its real instance. It means, the returned inout object can be converted to arbitrary qualifiers without type system breaking.

Two years ago I opened an enhancement issue: https://issues.dlang.org/show_bug.cgi?id=13006

And posted a pull request. https://github.com/D-Programming-Language/dmd/pull/3740

Kenji Hara


April 15, 2016
On Friday, 15 April 2016 at 03:10:12 UTC, Andrei Alexandrescu wrote:
> We want Phobos to be beautiful, a prime example of good D code. Admittedly, it also needs to be very general and efficient, which sometimes gets in the way. But we cannot afford an accumulation of mad tricks to obscure the large design.
>
>
> Andrei

Why didn't we go with all functions being able to infer const, pure etc rather than just templates?

April 15, 2016
On Friday, 15 April 2016 at 03:10:12 UTC, Andrei Alexandrescu wrote:
> Consider:
>
> https://github.com/D-Programming-Language/phobos/blob/master/std/range/primitives.d#L152
>
> There is no explanation to it in the source code, and the line blames to https://github.com/D-Programming-Language/phobos/pull/2661 (irrelevant).
>

I've been wondering what that is myself, so I've just cargo-cult-copied it into my code. Thanks for the post.
April 15, 2016
On Friday, 15 April 2016 at 04:23:29 UTC, Jonathan M Davis wrote:
> Certainly, there have been a few times that it's come up in D.Learn when folks ask what the heck it is, so there should be a few posts floating around with an explanation. This is the only useful post that I could find in a quick search though:
>
> http://forum.dlang.org/post/mh68p8$2p56$1@digitalmars.com

He says:
> Alternatively, you could have the lambda take an R as a parameter. Or fix the semantics ...

Assuming it works OK, that seems much cleaner:

(R r)
{
    if (r.empty) {}
    ...
}


April 15, 2016
On 4/15/16 8:59 AM, Nick Treleaven wrote:
> On Friday, 15 April 2016 at 04:23:29 UTC, Jonathan M Davis wrote:
>> Certainly, there have been a few times that it's come up in D.Learn
>> when folks ask what the heck it is, so there should be a few posts
>> floating around with an explanation. This is the only useful post that
>> I could find in a quick search though:
>>
>> http://forum.dlang.org/post/mh68p8$2p56$1@digitalmars.com
>
> He says:
>> Alternatively, you could have the lambda take an R as a parameter. Or
>> fix the semantics ...
>
> Assuming it works OK, that seems much cleaner:
>
> (R r)
> {
>      if (r.empty) {}
>      ...
> }

That makes other unittests fail (those with noncopyable ranges).

Overall we really need to spend some time on making Phobos simpler and better. The mishmash of styles and variable quality of contributions has slowly been gnawing at the sheer quality of the code.


Andrei

April 15, 2016
On Friday, 15 April 2016 at 09:07:27 UTC, Timon Gehr wrote:
> Related: Phobos should never use is(typeof(...)). Contrary to popular belief, is(typeof(...)) is not the same as __traits(compiles,...).


I don't think it should be using __traits(compiles) either. I'd prefer to see built from the other reflection primitives... though I'll grant that compiles is flexible.

hasMember!(Range, "empty")

isn't as specific as the current test... and

is(typeof(Range.init.empty) : bool)

isn't as flexible (I don't think that takes an empty that returns an opCast:bool item)


But regardless, I still kinda prefer the idea of building these reflection helper functions so they do cover the cases nicely...

then a helper function that takes a list of conditions and tells you which one failed... hmm, this is getting interesting.
April 15, 2016
On 04/15/2016 06:50 AM, Kenji Hara via Digitalmars-d wrote:
>
>
> You should recall the history of inout.
> http://wiki.dlang.org/DIP2
>
> At first, It has designed to temporarily squash mutable/const/immutable
> qualifiers on function argument inside function body. Therefore when
> inout qualifier appears in function return type, but doesn't on
> parameter types, we defined it an error.
>
> However, I concluded that we can remove the restriction. When an inout
> object arises from thin air, no one holds the qualifier of its real
> instance. It means, the returned inout object can be converted to
> arbitrary qualifiers without type system breaking.
>
> Two years ago I opened an enhancement issue:
> https://issues.dlang.org/show_bug.cgi?id=13006
>
> And posted a pull request.
> https://github.com/D-Programming-Language/dmd/pull/3740

I do recall the history. The enhancement is sensible in a frame of mind "we need to keep inout" but I'm looking at top level and thinking, crap we can put up with a little duplication if we get rid of inout. It's just a prime example of apparently simple idea gone bonkers.

In all of my recent code I've avoided inout and didn't miss it one bit. There's no need for it - I replace it with one-liners that forward to template functions, which in turn deduce qualifiers and all is great.

Andrei