forbes at lindesay.co.uk (2016-09-16T09:53:36.147Z)
On 09/12/2016 05:32 PM, Danielle McLean wrote:
> In current ECMAScript, it is legal to place a variable declaration inside the
> initialiser of a `for` loop, as well as to declare the variable used by a
> `for...in` or `for...of` loop within the declaring expression:
>
> for (let i = 0; i < 5; ++i) console.log(i);
> for (let item of collection) process(item);
>
> When this syntax is used with `let` or `const`, the resulting variable is
> scoped to the loop and is not visible to the rest of the surrounding block.
>
> I propose that this syntax be extended, making it legal to place a variable
> declaration within the condition of an `if` or `while` statement. Any truthy
> value will cause the `if` block to run or `while` loop to repeat, as usual -
> the advantage is that the particular truthy value is bound to a variable and
> can be used inside the conditional block.
My initial reaction was positive, but now I don't think it works.
First, other places in the grammar do not restrict let/const to a single
variable. Should
```js
if (let a=0, b=1, c=0) { ... }
```
execute the if block or not? The obvious solution is to require a single
variable, which means the grammar for these let/consts is different from
others. What about
```js
x = { a: 1 };
if (let {a} = x) { ... }
```
Second, that previous example makes it unclear to me at first glance
what the intended semantics *should* be. I could imagine this printing
either 1 or 2:
```js
h = { foo: 0};
if (let {bar=1} = h) {
print(1);
} else {
print(2);
}
```
Is the conditional based on the variable's final value, or on whether or
not the destructuring found a match? I could argue for either one, so
even if there's a natural way to resolve my first problem, I think the
code looks ambiguous to the eye.
```js
if (let { children } = node) {
print("interior node");
} else {
print("leaf node");
}
```
Again, the simplest way to resolve this is to restrict it to "let/const
IDENTIFIER = expression", but it feels weird to have different rules for
this particular case. for(let...) on the other hand, does not attempt to
use the let expression as a value, so it does not encounter any of these
problems.
As a minor issue, it also feels a little awkward to special-case this
conditional expression. I can do
```js
if (let x = foo()) print(x)
```
but not
```js
(let x = foo()) && print(x)
```
On 09/12/2016 05:32 PM, Danielle McLean wrote: > In current ECMAScript, it is legal to place a variable declaration inside the > initialiser of a `for` loop, as well as to declare the variable used by a > `for...in` or `for...of` loop within the declaring expression: > > for (let i = 0; i < 5; ++i) console.log(i); > for (let item of collection) process(item); > > When this syntax is used with `let` or `const`, the resulting variable is > scoped to the loop and is not visible to the rest of the surrounding block. > > I propose that this syntax be extended, making it legal to place a variable > declaration within the condition of an `if` or `while` statement. Any truthy > value will cause the `if` block to run or `while` loop to repeat, as usual - > the advantage is that the particular truthy value is bound to a variable and > can be used inside the conditional block. My initial reaction was positive, but now I don't think it works. First, other places in the grammar do not restrict let/const to a single variable. Should if (let a=0, b=1, c=0) { ... } execute the if block or not? The obvious solution is to require a single variable, which means the grammar for these let/consts is different from others. What about x = { a: 1 }; if (let {a} = x) { ... } Second, that previous example makes it unclear to me at first glance what the intended semantics *should* be. I could imagine this printing either 1 or 2: h = { foo: 0}; if (let {bar=1} = h) { print(1); } else { print(2); } Is the conditional based on the variable's final value, or on whether or not the destructuring found a match? I could argue for either one, so even if there's a natural way to resolve my first problem, I think the code looks ambiguous to the eye. if (let { children } = node) { print("interior node"); } else { print("leaf node"); } Again, the simplest way to resolve this is to restrict it to "let/const IDENTIFIER = expression", but it feels weird to have different rules for this particular case. for(let...) on the other hand, does not attempt to use the let expression as a value, so it does not encounter any of these problems. As a minor issue, it also feels a little awkward to special-case this conditional expression. I can do if (let x = foo()) print(x) but not (let x = foo()) && print(x)