C++ has three categories of constness - the default one, so "mutable", mutable
which walks around const
, and const
, which stops modification, but not of mutable
members. This is obviously kind of backwards, and that's because the default is not immutable.
Rust has two categories of constness - the default one, so immutable, and mut
, which marks a declaration as mutable. This is also obviously wrong, because you cannot have a "this might be mutated, but you cannot do that" kind of a, say, argument to a function. One could say this is justified, because it makes creating data races harder, but I'd like to argue that that is not true in any aspect, at least in the "mutable and non-unique means an actor" model of Vapor.
Vapor has three categories of reference constness:
- the default one, so immutable; the default kind of a reference is called "a reference to an immutable object"
mutable
, which allows modification to an object. You can have multiple references to amutable
object, but once you have more than one, functions not markedsynchronized
are run asynchronously, never more than one at a time - in a way that mostly follows the actor model; the reference of this kind is called "a reference to a mutable object"const
, which is the thing I consider Rust to lack - it can bind to bothmutable
and immutable objects, makes mutation of state impossible, and generates the optimal code in both cases; when bound tomutable
, it behaves as if it was amutable
reference (other than making mutation impossible), and when bound to immutable, it behaves as if the reference was to an immutable object. Conceptually, this models a contract: "I won't change the state of your object, and I don't care if you will", while also keeping synchronization in effect. This kind of a reference is called "a const reference", becauseconst
applies to the reference itself, not the type it refers to (unlikemutable
).