On Tuesday, 30 July 2019 at 05:30:30 UTC, Jonathan M Davis wrote:
In principle, it's good to use const when you know that data isn't going to change, but that gets far more complicated when you're dealing with generic code or even with classes, since as soon as you use const, everything used with that template then needs to work with const, or in the case of classes, every derived class has to use const for their override of that function. Sometimes, that's fine, but that's usually when you're either requiring that const always work, or you're in control all of the code involved, so you know that you're not going to have to deal with issues like caching. It's issues like this that led us to decide a while ago that putting functions on Object was a mistake, since it locked all classes into a particular set of attributes (and even if we changed which attributes those were, it would still cause problems). The ProtoObject DIP (which would add a base class for Object that didn't have anything on it) will hopefully fix that, but that still hasn't been finalized yet.

In the case of ranges, on top of the general issues with const and generic code, their API just isn't designed with const in mind. Fundamentally, you need to be able to mutate a range to iterate through it. It would be different if we'd gone with more of a functional-style, head/tail solution where you have a function like head to get the first element, and a function like tail to return a range with the first element popped off, but for better or worse, that's not the direction we went. However, even if we had, issues like caching or delayed calculation would still come into play, and if you require that const work on something like empty, that prevents certain classes of solutions. Of course, on the flip side, without const, you don't know for sure that unwanted mutation isn't happening, but what would really be needed would be some kind of "logical" const rather than the full-on const we currently have, and that would be very difficult to implement. C++'s const _sort_ of allows that, because it has so many loopholes, but on the flip side, you lose most of the guarantees, and it mostly just becomes documentation of intent rather than actually enforcing logical constness. In practice, I find that D's const tends to not be terribly useful in generic code, but it's far more of a problem with libraries that are publicly available than with code where you control everything and can change stuff when you need to. This article I wrote goes into further detail about the issues with const in general:

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

The situation with ranges would be improved if we had some kind of const or inout inference for templated code like we do with other attributes, but I don't know quite how that would work or what the downsides would be.

- Jonathan M Davis

That was a great article you wrote. Const has been one of the more difficult concepts for me to grasp when I moved from python to C++ and then to D. I also never understood immutable and the difference with const. Your article makes that really clear. Thanks for sharing.

Matt

Reply via email to