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