Proposal: anaphoric if and while syntax

Steve Fink sphink at gmail.com
Thu Sep 15 18:29:16 UTC 2016


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)



More information about the es-discuss mailing list