I would like to propose a mut keyword that simply provides visual balance to the let keyword.
E.g.
let x = 6
mut thing.value = x
The idea is purely to provide visual balance and make it clear when something mutable occurs; this should act as a reminder to new users that they need to define a variable as mutable in order to mutate it.
It also helps to make it clearer when you’re about to make the mistake of trying to modify a non-mutable reference.
“mut” is an attribute that occurs in NINE different productions of the Rust grammar. It is not a verb. I’m sure some of the Rust language team can explain this further.
Correct, this is not about bindings. I am not aware of the details of the whole language so I can’t say if this wouldn’t fall apart in practice, but just as the “dyn” keyword has been forced on Trait objects, purely for a heads-up warning to the developer “WARNING: THIS ISN’T STATIC!”, I’d like a “mut” keyword so that as you scan the code you can see “modification happens here”.
If new users do take to writing it by default, then it only helps when the compiler spits out the warning “you are trying to mutate a thing here, but it’s not defined as mutable --> here”.
IMO
let x = 6
mut thing.value = x
looks better than
let x = 6
thing.value = x
especially when scanning code quickly, it allows you to identify the assignments out from function calls etc.
In the Rust grammar, let occurs in condition sub-expressions within if and while expressions, as well as in one of the four alternative productions for statements.
In my experience, relatively few = assignment statements are instances of delayed initialization of immutable variables. If that’s also the case for the OP, they could handle those cases by annotating only those assignment statements:
let foo;
\*!mut*\ foo = bar;
All other assignment statements [added: without a let prefix] in the program would be presumed to be assignments or reassignments to mut variables.
For the record, here are the current instances of the “mut” keyword in the productions of the draft grammar for Rust that is being developed by the grammar-wg. (In the following, … means that the production contains other alternatives that are not shown.)
The cognitive dissonance here is that let is a keyword that results in binding a type and/or an evaluated expression to an identifier. mut is simply an attribute of that binding, conceptually no different than & or static or const or ref or a lifetime 'a.
IIUC, the OP’s proposal is to prefix that one attribute to assignment statements when the target of the assignment has that attribute. Should the same promotion of attributes to the beginning of statements occur for other attributes? Would it make sense to prefix assignment statements for references with &?
This is just a normal block { /* code */ }, so {thing} moves thing, then .value accesses the place on that temporary, which is then = x assigned and ; then tossed.
You’ll somewhat rarely see {x} used to enforce a move on x rather than treating it as a place. (Personally, I typically end up creating a fn coerce<T>(t: T) -> { t } that I use to enforce moves. It’s nice for being able to write e.g. coerce::<&str>(&String) as well since type ascription in expressions isn’t anywhere near stable yet.)
Sorry, I can't understand this part yet. What exactly we access if braces here are just normal block? Right now for me it's the same as write { let x = 5; println!("{}", x); }.some_field - what is the difference?
Nothing. It’s literally just a block. The value of the block is the value of the final expression. So if the block only has one expression, then that is the value. Therefore the value of {x} is just the value of x itself.