Sorry for silly question, but I have been away from C++ for a long time now. How do these immutable function parameters properties differ from const parameters?
In D, we discovered both const and immutable annotations were required. Immutable means the object never changes. Const means the object cannot be altered via the const reference, but can be altered by mutable reference to the same object. This makes optimization based on immutability possible, it also means immutable objects can be shared among multiple threads without synchronization.
Both const and immutable attributes are transitive, meaning they are "turtles all the way down." People who are used to C and C++'s non-transitive const find it a bit difficult to get used to; people who have used functional languages find it liberating, and it makes for much easier to understand code.
> Const means the object cannot be altered via the const reference, but can be altered by mutable reference to the same object.
Given that this discussion is already going deep into the implementation level, isn't it possible to flag an object as immutable if it's declared and initialized as a const object, or is a const reference to said const object?
It's because const pointers aren't "deeply" immutable. For example, if we have a const Car*, we can reach into it to grab a (non-const) Engine* through which we can modify things.
If there was a "imm" keyword in C++ which acted "deeply", that would get us pretty far towards our goal here. However, we'd then find ourselves in cases where we need to (for example) cast from an imm Engine* back to a (non-const) Engine*, often for values returned from functions. That's what this new "region borrow checker" concept would solve.
> For example, if we have a const Car, we can reach into it to grab a (non-const) Engine through which we can modify things.
Isn't that already deep within undefined behavior territory?
That hardly is an adequate example, given that it spells an eggregious fault, the kind that's covered by any intro to C++ course with clear indications that it's nonsense.
A const object can still have a const pointer to a non const object. It's a source of much confusion and I've seen such errors often in our own code base.
Immutability is not so simple in C++ as it might first appear.
A const object can also still have mutable data. const_cast can just remove the 'const' attribute entirely, but even ignoring that "abuse" there's also the 'mutable' keyword which allows fields to be modifiable on const objects.
The rationale for "mutable" is similar to the one for interior mutability in Rust. It's actually really hard to define what it means for something to be "constant" in a systems language, and that's why Rust did not consider deeper sorts of immutability or functional purity.
Not irritating at all. You are saying that you can't swap the pointed at object for another one AND that you can't change the pointed at object. Two very different things.
You have four possible combinations all with different meanings.
It's also why I always I insist on putting const to the right of the declaration part the const is referring too. The C++ standard allows const to the left IF it is the first const. But I think this flexibility is kind of garbage....
True, but I am a little sensitive to a multiplicity of keywords on a line.
Agree about the variable placing being not great. The trouble is most folk use the flexibility to bind the const in the wrong direction, myself included. Then putting it "right" looks "wrong".