Head Const

Ola Fosheim Grøstad via Digitalmars-d digitalmars-d at puremagic.com
Tue Feb 16 08:01:26 PST 2016


On Tuesday, 16 February 2016 at 15:33:03 UTC, Jonathan M Davis 
wrote:
> const guarantees that the data will not be mutated via that 
> reference to the data. It guarantees nothing about other 
> references to that data. For that, you need immutable.

Yes, it's as weak as C++ const in most cases from an optimization 
POV.

In C (and some C++ compilers) you can say that there is no 
aliasing by using "restrict", so I guess what I want is something 
like "const restrict".

https://en.wikipedia.org/wiki/Restrict

> But as long as const guarantees that the data can't be mutated 
> via that reference, then there's plenty of code where the 
> programmer can look at it and know for sure that that data 
> isn't being mutated, because they know that the code in

When you are calling a function that is no-global-access "pure", 
yes.

> If casting away const and mutating is defined behavior, then 
> you lose that guarantee, and instead of knowing that some code 
> doesn't have access to a mutable reference to that data being 
> enough, you have to actually know what the code does to know 
> that it's not casting away const and mutating.

Yes, I agree that casting away const as is possible in C++ is 
bad. The only reasonable setting for doing so is when you call 
legacy functions that are not defined to be const, but 
implemented as such.

> Having @mutable would be better than allowing casting away 
> const and mutating to be defined behavior (at least when the 
> underlying data is mutable rather than immutable), because it 
> would at least restrict the data that can be mutated, and it 
> would guarantee that you don't accidentally mutate an immutable 
> variable (since it would make no sense to have a type with an 
> @mutable member be immutable, whereas if you're casting away 
> const, getting that right would be completely up to the 
> programmer).

Maybe I misunderstand, but I am likely to want an immutable 
object with a mutable field, e.g. ref-counted caching. You use a 
CAS instruction on the mutable ref-counter and share the data. 
Then you can flush the cache and release all objects that have a 
refcount of only 1 (the cache index pointer).

> But having @mutable would  still mean that you can't rely on a 
> const variable not being mutated when you pass it to a function 
> that you know doesn't have access to a mutable reference to the 
> same data. If you knew that no @mutable was involved, it would 
> be the same as now, but you'd have to know for sure that 
> @mutable was involved, and even if it isn't now, it could be 
> later after refactoring.

Well, yes, this is where you have to be very clear about what 
kind of semantics a struct is meant to have. I don't feel this is 
very clear in the current language.

To me the value of immutable is that fields that are immutable 
will remain immutable forever. Like for a key that is inserted 
into a hash table. You know that it cannot change so you never 
need to recompute the hash value.

Then I'd like to see a "limited time immutable", like the 
"restrict const" suggested above.

But apparently there are use-cases where you'd want to say "whole 
object is immutable" and other use-cases where you want to say 
"all non-forced-mutable fields are immutable".

> So, having @mutable would be far better than having it be 
> defined behavior to cast away const and mutate (assuming that 
> the underlying data is mutable rather than immutable), but 
> you're still losing out on guarantees that we have now.

Yes. But I think you could distinguish between what you specify 
and what you require. So you could specify "I only want wholly 
immutable things" in a function signature, and specify "this 
object is mostly immutable except for these mutable exceptions" 
when defining it.

So I think you can have both?



More information about the Digitalmars-d mailing list