this is why let and const should *never* have been introduced.  if we had stuck 
with just var, none of these petty-arguments and bickering among 
team-members/shops on scoping-styles that ultimately have *zero* productivity 
or benefit to web-projects would be possible.

and there's nothing wrong with pre-declaring all variables at the top-level of 
a function (which is an es5 best-practice that’s still valid today), regardless 
whether some are only used in conditional-blocks or not, like this real-world 
example [1]:

```
local.validateBySwaggerSchema = function (options) {
/*
 * this function will validate data against schema
 * http://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5
 */
    var $ref,
        circularList,
        data,
        dataReadonlyRemove2,
        ii,
        oneOf,
        schema,
        test,
        tmp;
...
        // dereference schema.$ref
        $ref = schema && schema.$ref;
        if (!$ref) {
            break;
        }
...
    tmp = typeof data;
    if (tmp === 'object' && Array.isArray(data)) {
        tmp = 'array';
    }
...
    if (schema === local.swaggerSchemaJson.definitions.jsonReference) {
...
    }
...
};
```

[1] https://github.com/kaizhu256/node-swgg/blob/2018.2.1/lib.swgg.js#L4076 
<https://github.com/kaizhu256/node-swgg/blob/2018.2.1/lib.swgg.js#L4076>

-kai

> On Mar 21, 2018, at 7:15 PM, Jordan Harband <[email protected]> wrote:
> 
> ```
> if (someComplicatedCondition()) {
>   doSomeLogic();
>   doSomeOtherLogic(if.value, true);
> }
> ```
> 
> On Wed, Mar 21, 2018 at 2:52 AM, Rodrigo <[email protected] 
> <mailto:[email protected]>> wrote:
> Here are my gripes with `let` and `const` returning values:
> 
> 1) declaration lists are hard to read:
> 
>     if ((let x = 10, y = 20) > 15) {
>         // true, but what's being compared here? 10 or 20? (answer: 20)
>     }
> 
> Although right now this is allowed and the last element is compared:
> 
>     if ((x = 10, y = 20) > 15) {
>         // result is true, 20 > 15
>     }
> 
> 2) Destructuring assignments are also confusing, what's being compared here?
> 
>     if(let [x,y] = [1,2]) {
>     }
> 
> Again, this is allowed as of today:
> 
>     if([x,y] = [1,2]) {
>         // true, as it returns [1,2]
>     }
> 
> 3) Nesting `let/const` would be either expected everywhere (not only
> in the `if`) or a possible side effect from the implementation.
> Similar to languages such as Perl.
> 
>     let x = foo(let y = 100, z = 200);  // what's the scope of x and z?
> 
> This leads to hard to read and very confusing code golf.
> 
> That's why Golang went with something simple,
> `if([declaration];[conditional])`, and avoided confusion over `:=`
> assignments returning values anywhere in the code. `x:=( y:= 20 )` is
> not allowed in Go.
> 
> It expands on the 45-year tried-and-true structure of `for(;;)` to
> create `if(;)` and keep the ES language simple and clear expanding on
> its own concept of `for(;;)`.
> 
> On Wed, Mar 21, 2018 at 7:57 AM, Naveen Chawla <[email protected] 
> <mailto:[email protected]>> wrote:
> > OK I neglected to read the original post fully. My last post example would
> > be based on allowing `const` and `let` declarations to expressions in of
> > themselves (in the case of multi variables, returning the last one). So let
> > me ask, what exactly would be the problem with this?
> >
> > On Wed, 21 Mar 2018 at 12:20 Naveen Chawla <[email protected] 
> > <mailto:[email protected]>> wrote:
> >>
> >> What would `if.value` look like in an example?
> >>
> >> Wouldn't it be possible to have something like `if(const x = getX() &&
> >> const y = getY())` to capture more than just the conditional if required?
> >> I'm guessing that would probably break something somewhere, but I'm not 
> >> sure
> >> what.
> >>
> >> On Wed, 21 Mar 2018 at 04:35 Jordan Harband <[email protected] 
> >> <mailto:[email protected]>> wrote:
> >>>
> >>> Is the use case only ever to capture the thing that serves as the
> >>> conditional?
> >>>
> >>> If so, would perhaps something like `if.value` work better? Since it's a
> >>> keyword, it could be made to only work in the `if` block, and you wouldn't
> >>> need any of that odd multi-statement stuff in the conditional parens.
> >>>
> >>> On Tue, Mar 20, 2018 at 12:57 PM, Rodrigo <[email protected] 
> >>> <mailto:[email protected]>> wrote:
> >>>>
> >>>> Proposal: inline let/const statements to declare and initialize
> >>>> variables within if statements, so that temporary variables exist only
> >>>> within the if/else block scope.
> >>>>
> >>>> Reason: limits variable scope to the block where really needed, in
> >>>> similar fashion to variables defined in for(;;) statements. This
> >>>> improves readability while reducing unnecessary variables roaming
> >>>> outside their needed block.
> >>>>
> >>>> The syntax would be very similar to the for(;;) assignment/test pair:
> >>>>
> >>>>     if (let x = 100; x > 50) {
> >>>>         console.log(x); // 100
> >>>>     }
> >>>>     console.log(x); // ReferenceError
> >>>>
> >>>>     // same for const
> >>>>     if( const x = foo(); typeof x === 'object' ) {
> >>>>         //...
> >>>>     }
> >>>>
> >>>>     // the variable is available within any else block
> >>>>     // after its declaration
> >>>>     if (let x = foo(); x < 50) {
> >>>>         console.log(x);  // y is not available here
> >>>>     } else if (let y = bar(); y > 0) {
> >>>>         console.log(x, y);
> >>>>     } else {
> >>>>         console.log(x, y);
> >>>>     }
> >>>>
> >>>> Right now there isn't a way to limit a variable to the if block:
> >>>>
> >>>>     let x = 100;
> >>>>     if (x > 50) {
> >>>>         console.log(x);
> >>>>     }
> >>>>     // x is in scope, but may not be needed beyond the if statement
> >>>>     console.log(x);
> >>>>
> >>>>     // or a non-strict assignment, which also "leaks" scope
> >>>>     if( (x = 100) > 50 ) {
> >>>>         // ...
> >>>>     }
> >>>>
> >>>> There are many "workarounds" available, here's a few:
> >>>>
> >>>>     // workaround 1: can be remedied with a scope block
> >>>>     // but it's asymmetrical and non-idiomatic
> >>>>     {
> >>>>         let x = 100;
> >>>>         if (x > 50) {
> >>>>             console.log(x);
> >>>>         }
> >>>>     }
> >>>>
> >>>>     // workaround 2: with a for statement
> >>>>     // but this is non-idiomatic, hard to read and error-prone
> >>>>     for (let x = 100; x > 50;) {
> >>>>         console.log(x);
> >>>>         break;
> >>>>     }
> >>>>
> >>>> If-initialization is available in many languages (Go, Perl and Ruby
> >>>> come to mind) and are considered best practice in each one of them:
> >>>>
> >>>>     // Golang - x is defined, assigned and conditionally tested
> >>>>     if x := 100; x > 50 {
> >>>>         // x is in scope here
> >>>>     } else {
> >>>>         // and in here
> >>>>     }
> >>>>     // x is not available here
> >>>>
> >>>>     ###### Perl
> >>>>     if( my $x = 100 ) {
> >>>>         print $x;
> >>>>     }
> >>>>     print $x; # an error
> >>>>
> >>>>     if ( ( my $x = myfoo() ) > 50 ) {  # also ok in Perl
> >>>>         print $x;
> >>>>     }
> >>>>
> >>>>     ###### Ruby
> >>>>     if ( x = 100 )  # parens required per style guide
> >>>>         puts(x)
> >>>>     end
> >>>>     puts(x) # unfortunately Ruby does not limit scope to if, so x
> >>>> "leaks"
> >>>>
> >>>> I think this would be a great and important addition to the language.
> >>>>
> >>>> -Rodrigo
> >>>>
> >>>> PS: Just for the sake of comparison, Perl-style if-assignments could
> >>>> also be an
> >>>> option, albeit a very bad one IMO:
> >>>>
> >>>>     if( ( let x = 100 ) > 50 ) {
> >>>>     }
> >>>>
> >>>> A Perl-style, value-returning let/const has readability issues, opens
> >>>> quite a few fronts and sort of implies that let/const can return
> >>>> values anywhere in the code outside if/else. On the other hand it
> >>>> would fit with the currently if assignment if( x = y ). Definitely not
> >>>> recommended.
> >>>> _______________________________________________
> >>>> es-discuss mailing list
> >>>> [email protected] <mailto:[email protected]>
> >>>> https://mail.mozilla.org/listinfo/es-discuss 
> >>>> <https://mail.mozilla.org/listinfo/es-discuss>
> >>>
> >>>
> >>> _______________________________________________
> >>> es-discuss mailing list
> >>> [email protected] <mailto:[email protected]>
> >>> https://mail.mozilla.org/listinfo/es-discuss 
> >>> <https://mail.mozilla.org/listinfo/es-discuss>
> _______________________________________________
> es-discuss mailing list
> [email protected] <mailto:[email protected]>
> https://mail.mozilla.org/listinfo/es-discuss 
> <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