I understand the fear about "bad code" potentially sprouting from it. I
guess I'm not as bothered as long as I can do what I want. So it's a matter
of how heavily weighted the "potential bad practice" concern is over
developer power.

The advantage is that it's as powerful as the developer wants it to be, and
makes the common cases in `if` and `while` easy to learn and do.

For example, you can do while( x > (const y = getYFromX(x) ) ), which none
of the other ideas directly allow.

Which brings me to the next point. How would otherwise do this in a while
loop? I presume the while(;) based initialization part would only operate
at the start of the loop, to be consistent with for loops. So how would you
make a scoped variable initialization on every iteration?

On Sun, 25 Mar 2018 at 03:21 Isiah Meadows <[email protected]> wrote:

> I disagree, I feel it's too clever. It'd make sense in a control flow
> statement where in the alternate branch, the value is
> meaningless/useless/ineffable/etc. (and this is why `for` loops
> commonly allow such syntax already), but in ordinary function calls,
> it seems like it's just trying to golf the code without good reason.
>
> It's not visually ambiguous, just pointless in my opinion (a solution
> in search of a problem).
>
> -----
>
> 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 Sat, Mar 24, 2018 at 7:54 AM, Naveen Chawla <[email protected]>
> wrote:
> > I don't know why `foo(let x = 10)` would be a bad practice or hurt
> > readability.
> >
> > I find it perfectly readable and with obvious meaning!
> >
> > ```js
> >     foo(const x = 10)
> >     bar(x)
> > ```
> >
> > vs
> >
> > ```js
> >     const x = 10
> >     foo(x)
> >     bar(x)
> > ```
> >
> > I also find it "clean". So I guess these aren't really useful terms.
> >
> > As for the `if(const x = 5)` being like `if(x = 5)` being confused with
> > `if(x==5)`, `if(const x == 5)` would throw an error anyway.
> >
> > On Fri, 23 Mar 2018 at 20:02 Rodrigo <[email protected]> wrote:
> >>
> >> @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

Reply via email to