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

