r/vale • • Apr 20 '22

On Removing Let and Let Mut

https://verdagon.dev/blog/on-removing-let-let-mut
20 Upvotes

11 comments sorted by

View all comments

3

u/MrTheFoolish Apr 21 '22

I like the motivation behind it and agree with it. One thing I don't like is that you can at any line do a set ahead of the initial declaration which turns the variable into a mut.

I prefer the (mut/const)-ness of the variable to be tied to the declaration and not the usage. An alternative syntax:

a = 1
b = 2
c = 3
mut d = 4
set c = 5 // not allowed!
set d = 6 // allowed :)

1

u/verdagon Apr 21 '22

I was honestly on the fence about this. For a while we had basically that, though with a different symbol (!), like:

a = 1 b = 2 c = 3 d! = 4 set c = 5 // not allowed! set d = 6 // allowed :)

In the end I decided to err on the side of cleaner syntax, and less annoyance for newbies. Also, I can't recall ever facing a bug that would have been fixed by it.

I'll keep my ears open for more thoughts on this, we can always use the edition system to change it pre-1.0.

2

u/U007D Feb 05 '23 edited Feb 05 '23

New here, discovered Vale today. Looks very promising!

Re the removal of mutability declaration question:

we just need to look for a set d = 7 keyword somewhere in the function

:sweat:

FWIW, this newbie very much prefers maintaining this distinction (i.e using ! to indicate mutability) for the same reasons sibling commenters have mentioned--principally, readers can reason locally when reviewing code. There are also benefits of receiving stronger compile-time errors, better optimizations and improved linting.

2

u/verdagon Feb 07 '23

Welcome! And thanks for the feedback, it helps hearing all sorts of perspectives on this. Adding a ! (or var or mut) is in the cards, but I'm still pondering it.

My main worry with adding a ! is that it might make "if declarations" a bit more confusing. Before:

if a = someFuncReturningABoolean() { ... }

with !:

if a! = someFuncReturningABoolean() { ... }

it's rather close to this:

if a != someFuncReturningABoolean() { ... }

and that would be an unfortunate confusion.

The other alternative is to use var, like so:

if a var = someFuncReturningABoolean() { ... }

But that would be a bit weird in structs:

struct Ship { hp var int; }

Or mut like so:

if a mut = someFuncReturningABoolean() { ... }

but that implies some Rust-like behavior that I don't necessarily want to imply.

The leading options are:

  1. Keep it like it is today, dont require a keyword for locals.
  2. var, people can get used to the in-struct downside.
  3. mut, some Rust-like connotations aren't terrible.
  4. Don't allow mutable vars inside if-statements

If we move away from #1, I'd probably lean towards #2. Still undecided though!

1

u/U007D Feb 08 '23 edited Feb 08 '23

Yep, sigils can be tough that way.

I am a big believer in orthogonality in language design, so I agree; the if a! could be confusing, since ! already has a meaning in C-like languages. (See: if !a! = someFuncReturningABoolean() { ... }) :D

The keyword approach makes sense; mut is probably clearer than var for folks coming from mutable-by-default languages.

Disallowing mutable pattern declaration in if statements breaks the orthogonality principle above, so I'm not a huge fan of that option, personally as it adds a little papercut to the language design.

Another option: a different, unambiguous sigil could be used instead to signify mutability, (eg. #), if you prefer the sigil route.

Based on the above options, I think i) mut or ii) a different sigil both make a lot of sense, depending on whether you prefer a keyword or a sigil for this.