Thread overview
Why MapResult.empty() is not const in Phobos?
Jul 06, 2019
valmat
Jul 06, 2019
valmat
Jul 06, 2019
Jonathan M Davis
Jul 06, 2019
Exil
Jul 06, 2019
Jonathan M Davis
Jul 06, 2019
Exil
Jul 06, 2019
Timon Gehr
July 06, 2019
Minimal examples when it broke code:
https://run.dlang.io/is/HbEfkJ
https://run.dlang.io/is/4h1B6Z

July 06, 2019
On Saturday, 6 July 2019 at 05:37:10 UTC, valmat wrote:
> Minimal examples when it broke code:
> https://run.dlang.io/is/HbEfkJ
> https://run.dlang.io/is/4h1B6Z

PS https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d#L589
July 06, 2019
On Friday, July 5, 2019 11:37:10 PM MDT valmat via Digitalmars-d wrote:
> Minimal examples when it broke code: https://run.dlang.io/is/HbEfkJ https://run.dlang.io/is/4h1B6Z

In general, it can't be empty, because that would require that the range it's wrapping have a const empty, and most don't. The only way that map (or any wrapper range) can have a const empty would be if it goes to the effort of duplicating the function and uses static ifs to determine whether the version that's const will work or whether the version that's not const needs to be compiled in. And since const ranges are basically unusable, because they can't be iterated, going to that level of effort and making the code messy in that manner is arguably a waste of time.

- Jonathan M Davis



July 06, 2019
On Saturday, 6 July 2019 at 06:56:22 UTC, Jonathan M Davis wrote:
> On Friday, July 5, 2019 11:37:10 PM MDT valmat via Digitalmars-d wrote:
>> Minimal examples when it broke code: https://run.dlang.io/is/HbEfkJ https://run.dlang.io/is/4h1B6Z
>
> In general, it can't be empty, because that would require that the range it's wrapping have a const empty, and most don't. The only way that map (or any wrapper range) can have a const empty would be if it goes to the effort of duplicating the function and uses static ifs to determine whether the version that's const will work or whether the version that's not const needs to be compiled in. And since const ranges are basically unusable, because they can't be iterated, going to that level of effort and making the code messy in that manner is arguably a waste of time.
>
> - Jonathan M Davis

So phobos doesn't properly use const either, officially. Just one more reason not to use const on the pile.
July 06, 2019
On 06.07.19 07:37, valmat wrote:
> Minimal examples when it broke code:
> https://run.dlang.io/is/HbEfkJ
> https://run.dlang.io/is/4h1B6Z
> 

1. Because there is no const inference (yet?).
2. An immutable range makes no sense anyway. Note that trying to do C++-style "const-correctness" is not a good idea in D, mostly because of 1.

I.e., the problem is that you are using `const`.

Whatever comes out of this, slapping `const` on `MapResult.empty` is not the way to fix this.

Here's an example where a `const` somewhere in Phobos is actively breaking code:

import std.stdio, std.typecons;
struct S{
    string toString(){ return "not broken"; }
}
void main(){
    writeln(S()); // "not broken"
    writeln(tuple(S(),S())); // "Tuple!(S, S)(const(S)(), const(S)())" wtf?
}

This is just annoying.
July 06, 2019
On Saturday, July 6, 2019 10:18:49 AM MDT Exil via Digitalmars-d wrote:
> On Saturday, 6 July 2019 at 06:56:22 UTC, Jonathan M Davis wrote:
> > On Friday, July 5, 2019 11:37:10 PM MDT valmat via
> >
> > Digitalmars-d wrote:
> >> Minimal examples when it broke code: https://run.dlang.io/is/HbEfkJ https://run.dlang.io/is/4h1B6Z
> >
> > In general, it can't be empty, because that would require that the range it's wrapping have a const empty, and most don't. The only way that map (or any wrapper range) can have a const empty would be if it goes to the effort of duplicating the function and uses static ifs to determine whether the version that's const will work or whether the version that's not const needs to be compiled in. And since const ranges are basically unusable, because they can't be iterated, going to that level of effort and making the code messy in that manner is arguably a waste of time.
> >
> > - Jonathan M Davis
>
> So phobos doesn't properly use const either, officially. Just one more reason not to use const on the pile.

There really isn't a way to use const "properly" with ranges. The most that you could possibly do with a const range is query whether it's empty or get at a const version of front. And that's assuming that the range is implemented in a way that either of those would work and that any ranges that it wraps also have const on empty and/or front.

Maybe if we had a generic way to get a tail-const slice of a range, then const ranges would be more viable, but we don't, and with how restrictive D's const is, it wouldn't surprise me if plenty of ranges (especially those over containers) couldn't have tail-const slices anyway due to how they iterate internally. Either way, we don't have a way to get tail-const ranges other than with dynamic arrays, and the range API fundamentally requires that a range be mutable in order to be iterated. So, trying to use const with ranges quickly becomes a waste of time. Even if we regularly tried to go as far as we can go with const and the range API, it wouldn't get very far. D's range API is incompatible with const.

- Jonathan M Davis



July 06, 2019
On Saturday, 6 July 2019 at 18:01:12 UTC, Jonathan M Davis wrote:
> On Saturday, July 6, 2019 10:18:49 AM MDT Exil via Digitalmars-d wrote:
>> On Saturday, 6 July 2019 at 06:56:22 UTC, Jonathan M Davis wrote:
>> > On Friday, July 5, 2019 11:37:10 PM MDT valmat via
>> >
>> > Digitalmars-d wrote:
>> >> Minimal examples when it broke code: https://run.dlang.io/is/HbEfkJ https://run.dlang.io/is/4h1B6Z
>> >
>> > In general, it can't be empty, because that would require that the range it's wrapping have a const empty, and most don't. The only way that map (or any wrapper range) can have a const empty would be if it goes to the effort of duplicating the function and uses static ifs to determine whether the version that's const will work or whether the version that's not const needs to be compiled in. And since const ranges are basically unusable, because they can't be iterated, going to that level of effort and making the code messy in that manner is arguably a waste of time.
>> >
>> > - Jonathan M Davis
>>
>> So phobos doesn't properly use const either, officially. Just one more reason not to use const on the pile.
>
> There really isn't a way to use const "properly" with ranges.

As in annotating functions you want to guarantee won't make modifications to the object. Sure const ranges might be useless the way they are designed. But I still want to guarantee my empty() function doesn't make any changes. I can't do that because phobos doesn't properly annotate functions with const.