Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use 'mut' as alias for 'let mut' #65257

Closed
pbbob opened this issue Oct 9, 2019 · 20 comments · Fixed by #66994
Closed

Use 'mut' as alias for 'let mut' #65257

pbbob opened this issue Oct 9, 2019 · 20 comments · Fixed by #66994
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-help-wanted Call for participation: Help is requested to fix this issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@pbbob
Copy link

pbbob commented Oct 9, 2019

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.

❤️🦀

@RustyYato
Copy link
Contributor

RustyYato commented 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 mut to mut doesn'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 is let mut.

tldr: var wasn't rejected because of the name var, but because it allowed easy mutation, which runs counter to Rust's philosophy.

@pbbob
Copy link
Author

pbbob commented Oct 9, 2019

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 is let mut.

I politely disagree. In fact, it is actually the other way around. Using mut unnecessarily will cause compiler warnings, discouraging the use of unneeded mutability. The compiler doesn't warn when the use of mut is actually needed.

@RustyYato
Copy link
Contributor

RustyYato commented Oct 9, 2019

I politely disagree. In fact, it is actually the other way around. Using mut unnecessarily will cause compiler warnings

The fact that people will choose mut in the face of compiler warnings has been shown in practice, across many projects. Also, the problem isn't that people may choose to put mut just 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 used mut because 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 use mut because it is just as easy as making it immutable. So the problem is a bit more subtle than you seem to think.

@burdges
Copy link

burdges commented Oct 10, 2019

This solves the problems (readability, more concise) that people have with let mut

Incorrect. Extreme brevity harms readability. See Perl. lol

Readers would ignore the let vs mut distinction far more often that let vs let mut, partially due to length difference, but let mut works even better than say mutable.

It's true boilerplate often harms readability, but boilerplate requires some complexity be repeated, not merely the let in let mut.

It harms readability even further if mut also works for let 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, and default, not any shorter alternatives. And delegation RFCs have kinda given up the short syntaxes. I think Rust's omission of then is 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, or function, but actually just writing the shorter bare f(..) { .. } increases cognitive load. I think var invokes the minor linguistic subtlety that variable means mutable binding, while let acts like a common term for binding, which makes let mut very slightly clearer.

@sinkuu
Copy link
Contributor

sinkuu commented Oct 10, 2019

whilst not causing the issues that people have (pattern matching and consistancy)

The mut statement would be orthogonal to the current language in some sense though. let mut foo is not a special syntax, but is composed of let statement + mut foo pattern. It is in line with other places expects a pattern, where you can write match _ { mut x => ... }, for mut x in, or fn foobar(mut x: i32).

@Centril Centril transferred this issue from rust-lang/rfcs Oct 10, 2019
@Centril Centril added A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 10, 2019
@Centril
Copy link
Contributor

Centril commented 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:

mut x = 0;
--- help: missing `let`

The idea here is to check self.token.is_keyword(kw::Mut) && self.look_ahead(1, |t| t.is_ident()).

var x = 0;
--- help: to introduce a variable, write `let` instead of `var`

auto x = 0;
---- help: to introduce a variable, write `let` instead of `auto`

The idea here is to check:

is_ident_var_or_auto && !self.look_ahead(1, |t| is_brace(t))`

The relevant code is here:

Ok(Some(if self.eat_keyword(kw::Let) {
Stmt {
id: DUMMY_NODE_ID,
kind: StmtKind::Local(self.parse_local(attrs.into())?),
span: lo.to(self.prev_span),
}

cc @estebank

@Centril Centril added E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-help-wanted Call for participation: Help is requested to fix this issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. P-medium Medium priority labels Oct 10, 2019
@fmckeogh
Copy link
Member

fmckeogh commented Oct 10, 2019

@rustbot claim

@rustbot

This comment has been minimized.

@SimonSapin
Copy link
Contributor

@Centril Although I would also guess that the initial idea is very unlikely to end up accepted, it feels premature to unilaterally hijack the thread in your very first comment and make it have a different (and in a way opposite) purpose. Teams of the Rust project are designed to make decisions collectively. Improving diagnostics sounds good, but issue numbers are cheap.

@Centril
Copy link
Contributor

Centril commented Oct 10, 2019

@Centril Although I would also guess that the initial idea is very unlikely to end up accepted, it feels premature to unilaterally hijack the thread in your very first comment and make it have a different (and in a way opposite) purpose.

Implementing something as a diagnostic actually brings you closer to a working implementation -- I think more proposals should start out as diagnostics.

Teams of the Rust project are designed to make decisions collectively. [...]

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 issue numbers are cheap.

...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
Copy link
Member

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
Copy link
Contributor

nox commented Oct 10, 2019

This issue was literally in the RFCs repo initially, @Centril transferred it from there.

@carols10cents
Copy link
Member

Incorrect. Extreme brevity harms readability. See Perl. lol

@burdges Language bashing is not welcome here

@fmckeogh
Copy link
Member

@steveklabnik Wait, so should I unassign here, and assign to the new issue?

@Centril
Copy link
Contributor

Centril commented Oct 13, 2019

@Chocol4te Nah, just use this one.

@pbbob
Copy link
Author

pbbob commented Oct 14, 2019

Yeah, thats fine. You can just change this issue to be for diagnostics instead.

@fmckeogh
Copy link
Member

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 :(

@fmckeogh fmckeogh removed their assignment Oct 17, 2019
@Centril Centril self-assigned this Oct 17, 2019
@Centril
Copy link
Contributor

Centril commented 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
Copy link

I would like to help with this

@Centril
Copy link
Contributor

Centril commented 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. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-help-wanted Call for participation: Help is requested to fix this issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet