www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why MapResult.empty() is not const in Phobos?

reply valmat <ufabiz gmail.com> writes:
Minimal examples when it broke code:
https://run.dlang.io/is/HbEfkJ
https://run.dlang.io/is/4h1B6Z
Jul 05 2019
next sibling parent valmat <ufabiz gmail.com> writes:
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
Jul 05 2019
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Jul 05 2019
parent reply Exil <Exil gmall.com> writes:
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.
Jul 06 2019
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Jul 06 2019
parent Exil <Exil gmall.com> writes:
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.
Jul 06 2019
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
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.
Jul 06 2019