That strikes me as territory the 'do expression' proposal
https://github.com/tc39/proposal-do-expressions is more fitted for:
const x = do { if (c) expr; else { ... } };
What I'd like for this proposal is something that works consistently and
obviously for all blocks with a parenthesised element to them. When they're
formally separated by semi-colons, as in `for (a;b;c)`, each of `a,b,c`
acts as an expression. Why not allow any of those expressions to be
replaced by a statement block that acts like a do expression, each of
which's scope is nested under the previous one and are available to the
following block?
That didn't come out very clearly, so let's try with an example:
for ({
let x = 1, y = 2;
console.log("I'll be printed every loop!");
}; {
let s = 'some string';
if (y%7 === 0) x === y;
else x < 1000;
}; {
let s = 'some other string';
x+=1;
if (y%3 === 0) y += 2;
else y += 1;
}) {
// whatever code here
// local scope hierarchy is
// {
// x,
// y,
// __SCOPE__: {
// s: 'some string',
// __SCOPE__: {
// s: 'some other string'
// }
// }
// }
}
I'm just using some random logic in the blocks to illustrate the point: all
the variables declared in the blocks are accessible in the for block, but
the 'some string' `s` is masked by the 'some other string' `s` in the child
scope. The termination condition in the second block can vary each loop, as
can the iteration operation in the last block, and is simply the last value
in the block as-per do expressions.
On Thu, 22 Mar 2018 at 15:44 Mike Samuel <[email protected]> wrote:
> On Thu, Mar 22, 2018 at 3:50 AM, Isiah Meadows <[email protected]>
> wrote:
>
>>
>> I do have one other related thing I'd like to see: add a `let foo =
>> expr() else { ... }` variant, with a line terminator restriction
>> before the `else` so it can't be confused with an `else` within an
>> `if`.
>>
>
> Making it a restricted production would solve the grammatical ambiguity
> for existing code, but maybe in an errorprone way for future code:
>
> if (c) let foo = expr() else { ... } // else attaches to let
> if (c) let foo = expr(); else { ... } // else attaches to if
>
>
> Would the semantics differ from
>
> let foo = expr() || ({} => { ... })()
>
> ?
>
>
>
>
>
>>
>> -----
>>
>> Isiah Meadows
>> [email protected]
>>
>> Looking for web consulting? Or a new website?
>> Send me an email and we can get started.
>> www.isiahmeadows.com
>>
>>
>> On Thu, Mar 22, 2018 at 3:21 AM, Rodrigo <[email protected]> wrote:
>> > Not just let-scopes, but the introduction of `async/await` also
>> > welcomes the introduction of if-scoped variables.
>> >
>> > if (const data = await collection.find({}).toArray(); data.length >
>> 10)
>> > {
>> > console.log(data);
>> > } else if (data.length > 0) {
>> > console.log(data);
>> > } else {
>> > console.log(data);
>> > }
>> >
>> > And, as mentioned by @jerry, this can be extended to `switch` and
>> > `while`. Golang has `switch(;)` initialization too afaik.
>> >
>> > switch( const today = new Date(); today.getDay() ) {
>> > case 0:
>> > console.log( "Don't work on %s", today.toString() );
>> > break;
>> > }
>> >
>> > `while` would be a bit unnecessary, due to the fact that it can be
>> > replicated with `for( <assign>; <expression>; )`, but could be
>> > available for consistency with `if` and `switch`.
>> >
>> > El mié., 21 mar. 2018 19:47, Mike Samuel <[email protected]>
>> escribió:
>> >>
>> >>
>> >>
>> >> On Wed, Mar 21, 2018 at 1:27 PM, Sebastian Malton <
>> [email protected]>
>> >> wrote:
>> >>>
>> >>> Because block-level scoping is a very good way to avoid certain bugs
>> and
>> >>> is easier to reason about. Especially when considering project
>> successors.
>> >>
>> >>
>> >> +1. function-scoped variables in loop bodies caused tons of bugs
>> before
>> >> let-scoped variables and were a main motivating case.
>> >>
>> >> var i;
>> >> for (i = 0; i < arr.length; ++i) {
>> >> f(function () { /* Do something with */ arr[i]; });
>> >> }
>> >>
>> >> vs
>> >>
>> >> for (let i = 0; i < arr.length; ++i) {
>> >> f(function () { /* Do something with */ arr[i]; });
>> >> }
>> >>
>> >> Yes, linters got pretty good at finding uses of closed-over variables
>> >> modified in a loop, but the workarounds were not ideal.
>> >>
>> >> var i;
>> >> for (i = 0; i < arr.length; ++i) {
>> >> f(function (i) { return function () { /* Do something with */
>> arr[i]; }
>> >> }(i));
>> >> }
>> >>
>> >> Block scoping is just better for code that uses loops, variables, and
>> >> function expressions.
>> >>
>> >> _______________________________________________
>> >> es-discuss mailing list
>> >> [email protected]
>> >> https://mail.mozilla.org/listinfo/es-discuss
>> >
>> >
>> > _______________________________________________
>> > es-discuss mailing list
>> > [email protected]
>> > https://mail.mozilla.org/listinfo/es-discuss
>> >
>>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss