Repository navigation
Description
The idea of shortening let mut to var has been discussed many times before, and the general consensus always ends up being that it is not a good idea. I would like to propose something a bit different, so please hear me out.
I propose that instead of aliasing var to let mut, we instead just make mut expand into let mut when in the context of a variable declaration. For example:
let mut foo = 12;
// is identical to
mut foo = 12;This solves the problems (readability, more concise) that people have with let mut, whilst not causing the issues that people have (pattern matching and consistancy).
The most common issue people have with aliasing var to let mut is that it doesn't fit well with patterns, like let (x, mut y) = .... However, mut gets rid of this problem, because you wouldn't write let mut (x, mut y) if you were trying to pattern match, so why would someone want to write mut (x, mut y)? You wouldn't do that, and it wouldn't compile.
This would be optional, of course. let mut x = 1 would still work fine, and people would just have to option of removing the let to let it be implied.
There are a lot of other abbreviations used in rust (fn, mod, pub) that all serve the purpose of writing less. It just doesn't feel right that one of the most commonly used keywords is so long.
❤️🦀
Activity
RustyYato commentedon Oct 9, 2019
Rust wants to make to make you think when you try and use mutation, even if only a little bit, because mutation can be difficult to reason about. Shortening
let muttomutdoesn't fit this philosophy. Also, this makes mutation just as easy as no mutation. This will lead people to choose mutation because it will give them less compiler errors in the short term, and in doing so open themselves up to some weird bugs that could have been prevented with the syntactic salt that islet mut.tldr:
varwasn't rejected because of the namevar, but because it allowed easy mutation, which runs counter to Rust's philosophy.pbbob commentedon Oct 9, 2019
I politely disagree. In fact, it is actually the other way around. Using
mutunnecessarily will cause compiler warnings, discouraging the use of unneeded mutability. The compiler doesn't warn when the use ofmutis actually needed.RustyYato commentedon Oct 9, 2019
The fact that people will choose
mutin the face of compiler warnings has been shown in practice, across many projects. Also, the problem isn't that people may choose to putmutjust for the heck of it, but that they will unintentionally mutate something that was supposed to be immutable. And because it is being mutated, there is no warning, and they usedmutbecause it is their default, it is their default because it gets rid of compiler errors that say they were trying to mutate things that are immutable even though they weren't supposed to mutate them in the first place. They will usemutbecause it is just as easy as making it immutable. So the problem is a bit more subtle than you seem to think.burdges commentedon Oct 10, 2019
Incorrect. Extreme brevity harms readability. See Perl. lol
Readers would ignore the
letvsmutdistinction far more often thatletvslet mut, partially due to length difference, butlet mutworks even better than saymutable.It's true boilerplate often harms readability, but boilerplate requires some complexity be repeated, not merely the
letinlet mut.It harms readability even further if
mutalso works forlet mut, especially when you consider code readers need not actually know Rust.Rust syntax was designed largely to reduce cognitive load, not to reduce typing.
We use
return,continue, anddefault, not any shorter alternatives. And delegation RFCs have kinda given up the short syntaxes. I think Rust's omission ofthenis now considered a mistake, but presumably helps C programmers.Rust has short keywords only really for fundamental "items" used repeatedly by basically every module. It's similar cognitive load if you write
fn,func, orfunction, but actually just writing the shorter baref(..) { .. }increases cognitive load. I thinkvarinvokes the minor linguistic subtlety that variable means mutable binding, whileletacts like a common term for binding, which makeslet mutvery slightly clearer.sinkuu commentedon Oct 10, 2019
The
mutstatement would be orthogonal to the current language in some sense though.let mut foois not a special syntax, but is composed ofletstatement +mut foopattern. It is in line with other places expects a pattern, where you can writematch _ { mut x => ... },for mut x in, orfn foobar(mut x: i32).Centril commentedon Oct 10, 2019
It seems unlikely to me that we would support
mut $ident = $expr;as a short-hand. I'm personally opposed to it both because it adds unnecessary compiler complexity, stylistic schisms, and for the reasons outlined by @KrishnaSannasi.However, I've taken the liberty of reusing this issue towards improved diagnostics:
The idea here is to check
self.token.is_keyword(kw::Mut) && self.look_ahead(1, |t| t.is_ident()).The idea here is to check:
The relevant code is here:
rust/src/libsyntax/parse/parser/stmt.rs
Lines 44 to 49 in ece4977
cc @estebank
5 remaining items
Centril commentedon Oct 10, 2019
Implementing something as a diagnostic actually brings you closer to a working implementation -- I think more proposals should start out as diagnostics.
I will not bother the other language team members with not-fully-formed proposals that we will not accept in either case. I converted the issue into the most actionable and productive thing it could be.
The place for ephemeral discussions is either on Discord or on internals.
If you want to discuss this further, I'm available at Discord (but will not respond to it further here).
...but wasting everyone's time with things that will go nowhere (because it won't be accepted and because it is not important enough to be raised at the team) is not.
steveklabnik commentedon Oct 10, 2019
IMHO, the original thing this issue was opened for should be an RFC, not an issue. I'd have closed this, pointed the OP to the RFCs repo, and opened a new issue for the diagnostic issue.
nox commentedon Oct 10, 2019
This issue was literally in the RFCs repo initially, @Centril transferred it from there.
carols10cents commentedon Oct 11, 2019
@burdges Language bashing is not welcome here
fmckeogh commentedon Oct 13, 2019
@steveklabnik Wait, so should I unassign here, and assign to the new issue?
Centril commentedon Oct 13, 2019
@Chocol4te Nah, just use this one.
pbbob commentedon Oct 14, 2019
Yeah, thats fine. You can just change this issue to be for diagnostics instead.
fmckeogh commentedon Oct 17, 2019
I'm sorry, I've been pretty busy with coursework, and I'm still fighting my Python installation to even build the compiler, let alone make progress on this. Sorry :(
Centril commentedon Oct 17, 2019
I'll assign this to myself to work on when I have time. If you want to work on it however, feel free to work-steal it from me!
JesterOrNot commentedon Nov 6, 2019
I would like to help with this
Centril commentedon Nov 6, 2019
@JesterOrNot Sorry; should have updated this issue...! There's a PR #65811 at the moment. Feel free to leave suggestions on it if you like. :)
Auto merge of #66994 - Centril:stmt-polish, r=estebank