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 <rodrigol...@gmail.com> 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
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to