On Wednesday, 13 February 2019 at 16:40:18 UTC, H. S. Teoh wrote:
On Wed, Feb 13, 2019 at 11:32:46AM +0000, envoid via
Unfortunately, that guarantee also excludes a lot of otherwise
useful idioms, like objects that cache data -- a const object
cannot cache data because that means it's being mutated, or
lazily-initialized objects -- because once the ctor has run,
the object can no longer be mutated. Most notably, D's powerful
range idiom is pretty much unusable with const because
iteration over a range requires mutating the range (though
having const *elements* in a range is fine). This doesn't seem
as bad at first glance, but it wreaks havoc on generic code,
another thing that D is purportedly good at. It's very hard
(and often impossible) to write generic code that works with
both const and mutable objects.
So ironically, the iron-clad semantics of D's const system
turns out to be also its own downfall.
I agree that const by nature unfortunately kills lazy
initialization. However, I don't really understand why const is a
problem with ranges. Const elements are not a problem. Iterating
over a range consumes it (if I understand correctly). It does not
make sense to be able to consume a const object, so from my point
of view it's perfectly logical to disallow iterating const
ranges. If I'm missing something, please correct me.
I use const quite thoroughly in my project (a mahjong board game)
and in fact I am writing a blog post explaining how it helped me
understand what was happening in my code base. It enforces
encapsulated mutations. In classic OOP languages, mutable objects
propagate through the entire system, unless you actively create
an immutable copy of it (which is a lot of work for little gain).
If someone modifies your object on a place you don't expect (e.g.
creating and persisting data when rendering a read-only view), it
becomes hard to impossible to reason about the problem and debug
Refactoring in const was a lot of work, but I think it made my
code better in the end. I didn't run into any problems when using
it, except when I tried to modify an object where I should not
have (e.g. sorting a hand when rendering the view). I was able to
untangle the spaghetti because the compiler poked me about it. As
I didn't run into any problems and it helped clean up my code
base, I would recommend trying it.