@Naveen, I think it's best to avoid this road altogether and keep
initialization clean, even though assignment isn't.
The proposal is that given `for(;;)` hence `if(;)` instead of given
`x=y` hence `let x=y`.
But yes, `if( x = 5)` is already allowed, but it's confusing and hard to read.
Confusing on what is being compared on multiple statements: `if((const
x = 5, y = 10) > 0)`
Confusing when destructuring, on what's being compared: `if(let [x,y] = [1,2])`
Confusing when multiple statements: `if ((x = 10, y = 20) > 15)`
Looks like an error: `if( x = 5 )` versus `if( x == 5)`, did the
programmer forget the `=`?
And if you introduce nesting initializations everywhere outside the
`if`, that's basically an invitation for readability nightmare. `let`
and `const` anywhere introduce 2 conflicting best-practices:
- Rule 1: declare your variables that are used exclusively within `if`
blocks within the `if` parens
- Rule 2: don't declare variables within another statement (so that
people will refrain from doing `foo( let x=10 )`
Consider that, historically, other languages such as Perl allowed `if(
(my $x = 1) > 0)` and `foo( my $x = 100)` and became the ugly child of
power programming; whereas Golang, born much later, has limited
initializations to things such as `if( x:=1; x > 0)` and has kept
things quite minimalistic (and clear for the programmer).
```perl
# realworld example, hard to find variable declaration:
$redis->subscribe( 'queue', my $callback = sub {
...
});
```
On Fri, Mar 23, 2018 at 7:21 AM, Naveen Chawla <[email protected]> wrote:
> I'm still not seeing a compelling case for not allowing `const` / `let`
> declarations to be evaluated as expressions. Or I've missed it.
>
> As was noted,
>
> `if(x = 5)` is already allowed.
>
> Is `if(const x = 5)` really that much of a stretch?
>
> To answer a concern about a function call like `myFunction(const x = 7)`, of
> course the scope of `x` would be where it is declared. It can't be anywhere
> else (like inside myFunction or something).
>
> On Thu, 22 Mar 2018 at 22:53 Isiah Meadows <[email protected]> wrote:
>>
>> Probably true, more so than the `if (var ...)`/etc. (which can't be as
>> easily desugared). My `else` variant desugars more to something that
>> is also easily simulated, and it's a less common case:
>>
>> ```js
>> let foo = bar else return baz;
>>
>> // Desugared
>> let _tmp = bar;
>> if (tmp == null) return baz;
>> let foo = _tmp;
>> ```
>>
>> In this case, there's also the question of whether to require a
>> `return` in all code paths, which probably makes this a bit more
>> complicated than what would be worth for such a simple language
>> feature.
>> -----
>>
>> 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 12:23 PM, Michael Luder-Rosefield
>> <[email protected]> wrote:
>> > 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
>
>
> _______________________________________________
> 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