Mutable ForwardRange save() method not callable using const object

Jonathan M Davis newsgroup.d at jmdavisprog.com
Tue Sep 4 20:42:10 UTC 2018


On Tuesday, September 4, 2018 9:22:26 AM MDT Timoses via Digitalmars-d-learn 
wrote:
> On Tuesday, 4 September 2018 at 14:26:44 UTC, Steven
>
> Schveighoffer wrote:
> > [...]
> > As general advice, I wouldn't expect const to work well with
> > Ranges anyway -- const ranges are useless (you can't iterate
> > them). So not much code is expecting to handle const, including
> > the wrappers that Phobos provides.
>
> Thanks, that sounds like some good advice. I've actually bumped
> into this right after when I had an immutable range which was
> supposed to fill in its cache when being iterated.
> My argument for why this should work is that "from the outside of
> the range" it is immutable, since accessing via opIndex will
> always give the same value.
> ... In the end, that'll lead nowhere. The immutable attribute
> would become a "promise" rather than an enforcement (or too hard
> for the compiler to enforce).

That's simply not how const or immutable work in D though. They're actual
compiler guarantees, and it's undefined behavior to ever cast away const or
immutable and mutate the object. D's const is fundamentally different from
C++'s const in this regard. Not only is a const that doesn't provide
compiler guarantees useless according to Walter (though that's obviously
debatable), but the nature of immutable pretty much requires it. immutable
objects are implicitly shared, and in principle, they could end up in ROM.
So, even if your object is const, there's no guarantee that it's actually
mutable underneath the hood. The rigidness of D's const and immutable are
both a blessing and a curse. But the net result is we really can't have a
range API that works with them without more of a head/tail model (whereas
the current API mutates in place), and even if we had a head/tail model, it
would still get pretty hairy thanks to issues like reference counting.

So, as Steven points out, const and ranges don't go together at all. The
result is that a number of us use stuff like const and inout pretty
sparingly (at least outside of primitive types):

http://jmdavisprog.com/articles/why-const-sucks.html

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list