Per-iteration scoping would work just as it does with `for (const foo
of bar) { ... }` now, and if it were to make it in (I'm mildly against
the feature, BTW), I'd prefer it to be per-iteration like that.
-----

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 Sun, Mar 25, 2018 at 4:40 AM, Naveen Chawla <[email protected]> wrote:
> Obviously scoped, agreed, but again how would you allow scoped
> initialization upon each iteration, or is it your preference not to allow
> that? (again, initializers-as-expressions allows that, despite the other
> concerns).
>
> On Sun, 25 Mar 2018 at 10:57 Isiah Meadows <[email protected]> wrote:
>>
>> 1. My concern with `while` is that it's a little too duplicative of
>> C-style `for` functionally (although it's not an exact partial clone).
>> That's why I backtracked on it right as I proposed it (within the same
>> email).
>> 2. The scope would have been just like `if`, where it's scoped to the
>> body with an implicit inner block scope. Anything different would be
>> surprising and unintuitive.
>>
>> -----
>>
>> 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 Sun, Mar 25, 2018 at 12:55 AM, Naveen Chawla <[email protected]>
>> wrote:
>> > 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