A year back I dropped a proposal idea at the EcmaScript discussion list, I hope it get's picked up sometime.
My idea is that `let`, `var` and `const` return the value(s) being assigned. Basically I miss being able to declare variables in the assertion part of `if` blocks that are scoped only during the `if()` block existence (including `else` blocks).
Something along these lines:
if( let row = await db.findOne() ) {
// row available here
}
// row does not exist here
The current alternative is to declare the variable outside the `if()` block, but I believe that is inelegant and harder to read, and also requires you to start renaming variables (ie. row1, row2...) due them going over their intended scope.
As previous art, Golang's:
if x:=foo(); x>50 {
// x is here
}
else {
// x is here too
}
// x is not scoped here
> They are not ambiguous if you have the whole file in your head.
They're not ambiguous period, python's `=` always performs a local declaration unless overridden via the keywords you mentioned.
> This is why there are keywords like "global" & "nonlocal".
It's the exact opposite of your statement: `global` and `nonlocal` indicate non-local bindings, because by default all bindings are local and you do not need to have "the whole file in your head".
It's not the same. For instance, you could not use a `const` variable.
Also having "phantom" scope blocks get very nasty to read once you have more involved logic, as the block itself has no implied meaning and the programmer has to walk a few lines into it to get what's going on.
Would the else branch trigger on a falsy value, or on an exception? It's a bit confusing, as it looks like it would handle exceptions on the else branch, even though we know we have to wrap await in try/catch for that.
Other than saving a few characters (the variable name), I don't see any benefit of this, while it makes code harder to read.
Too bad the `with` [0] keyword has been reserved for crap, it sounds nice (not for this, but maybe for something else).
>> and also requires you to start renaming variables (ie. row1, row2...) due them going over their intended scope
Variable shadowing [1] is a really bad practice that makes it hard for people to collaborate and keep the code sane. Bad habits are not a reason for language changes.
If the `x` in the example was a const, it would throw an error because the code attempts to assign the value of `y` to `x`. You cannot assign a new value to a const.
In my opinion this is a terrible idea, since it's very easy (I do it all the time) to accidentally write `if (foo = bar)` instead of `if (foo == bar)`. If that were valid syntax it would be a huge footgun. I'd be onboard with it if it required a different syntax.
I'm down if you require a let/var/const in front of it:
if (foo = bar()) { // syntax error!
}
if (let foo = bar()) { // works fine
}
if (const foo = bar()) { // also works fine
}
if (var foo = bar()) { // also also works fine
}
My idea is that `let`, `var` and `const` return the value(s) being assigned. Basically I miss being able to declare variables in the assertion part of `if` blocks that are scoped only during the `if()` block existence (including `else` blocks).
Something along these lines:
The current alternative is to declare the variable outside the `if()` block, but I believe that is inelegant and harder to read, and also requires you to start renaming variables (ie. row1, row2...) due them going over their intended scope.As previous art, Golang's:
And Perl's