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 amutableobject, but once you have more than one, functions not markedsynchronizedare 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 bothmutableand immutable objects, makes mutation of state impossible, and generates the optimal code in both cases; when bound tomutable, it behaves as if it was amutablereference (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", becauseconstapplies to the reference itself, not the type it refers to (unlikemutable).