Proposal: if variable initialization

classic Classic list List threaded Threaded
45 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Proposal: if variable initialization

Rodrigo
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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Jordan Harband
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 <[hidden email]> 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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Naveen Chawla
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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Naveen Chawla
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Rodrigo
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
>>>> [hidden email]
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [hidden email]
>>> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Jordan Harband
```
if (someComplicatedCondition()) {
  doSomeLogic();
  doSomeOtherLogic(if.value, true);
}
```

On Wed, Mar 21, 2018 at 2:52 AM, Rodrigo <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
>>>> [hidden email]
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [hidden email]
>>> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

kai zhu
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
 */
    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) {
...
    }
...
};
```


-kai

On Mar 21, 2018, at 7:15 PM, Jordan Harband <[hidden email]> wrote:

```
if (someComplicatedCondition()) {
  doSomeLogic();
  doSomeOtherLogic(if.value, true);
}
```

On Wed, Mar 21, 2018 at 2:52 AM, Rodrigo <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
>>>> [hidden email]
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [hidden email]
>>> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Thomas Grainger
Is this sarcastic?

On 21 Mar 2018 12:58, "kai zhu" <[hidden email]> wrote:
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
 */
    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) {
...
    }
...
};
```


-kai

On Mar 21, 2018, at 7:15 PM, Jordan Harband <[hidden email]> wrote:

```
if (someComplicatedCondition()) {
  doSomeLogic();
  doSomeOtherLogic(if.value, true);
}
```

On Wed, Mar 21, 2018 at 2:52 AM, Rodrigo <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
>>>> [hidden email]
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [hidden email]
>>> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

kai zhu
@thomas, no.  i'm serious in my opinion that let and const were mistakes.

-kai

On Mar 21, 2018, at 9:01 PM, Thomas Grainger <[hidden email]> wrote:

Is this sarcastic?

On 21 Mar 2018 12:58, "kai zhu" <[hidden email]> wrote:
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
 */
    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) {
...
    }
...
};
```


-kai

On Mar 21, 2018, at 7:15 PM, Jordan Harband <[hidden email]> wrote:

```
if (someComplicatedCondition()) {
  doSomeLogic();
  doSomeOtherLogic(if.value, true);
}
```

On Wed, Mar 21, 2018 at 2:52 AM, Rodrigo <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
>>>> [hidden email]
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [hidden email]
>>> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Mike Samuel
In reply to this post by Rodrigo


On Tue, Mar 20, 2018 at 3:57 PM, Rodrigo <[hidden email]> 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.

With setters you can get some oddities because the getter need not return
the same value set.

const o = { get x() { return this.x_ }, set x(v) { return this.x_ = String(v) } }
if (!(o.x = 0)) {
  console.log('o.x is falsey: ' + !o.x);
}

If decorators are allowed on let/const declarations, then you might get a similar source of
confusion.

This might be especially confusing since in Java and C++ the result of an assignment is
the value actually assigned after any type coercion (or a reference to the left).

In JavaScript, the result of an assignment is the result of the right operand.
Though its a bit muddy, since the result of x++ is x coerced to a number for symmetry with x += 1.

If it turns out that decorators are widely used for type annotations on declarations and
some do custom coercion on assignment, does that introduce potential problems?






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Rodrigo
My proposal is to keep it simple and implement the if-assignment `if(
const o = ...; ! o ) { ... }` mimicking the `for(;;)` assignment
behavior.

That way we can scope a variable to the `if` block and we can do that
*separately* from assignment.

Assigning and comparing at the same time opens up all sort of oddities
as the variable transitions from lvalue to comparison operand. This
already exists in the language and is definitely not good practice.

`if.value`, as proposed earlier is a bombshell similar to `this`,
which could easily get scrambled with the introduction of additional
`if` blocks.

The beauty of `if(;)` is that it makes scope blocks possible while
avoiding the asymmetric behavior caused by assigning and comparing in
one go.

        if( let people=getTeamArray(); people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }



On Wed, Mar 21, 2018 at 2:37 PM, Mike Samuel <[hidden email]> wrote:

>
>
> On Tue, Mar 20, 2018 at 3:57 PM, Rodrigo <[hidden email]> 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.
>
>
> With setters you can get some oddities because the getter need not return
> the same value set.
>
> const o = { get x() { return this.x_ }, set x(v) { return this.x_ =
> String(v) } }
> if (!(o.x = 0)) {
>   console.log('o.x is falsey: ' + !o.x);
> }
>
> If decorators are allowed on let/const declarations, then you might get a
> similar source of
> confusion.
>
> This might be especially confusing since in Java and C++ the result of an
> assignment is
> the value actually assigned after any type coercion (or a reference to the
> left).
>
> In JavaScript, the result of an assignment is the result of the right
> operand.
> Though its a bit muddy, since the result of x++ is x coerced to a number for
> symmetry with x += 1.
>
> If it turns out that decorators are widely used for type annotations on
> declarations and
> some do custom coercion on assignment, does that introduce potential
> problems?
>
>
>
>
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Mike Samuel


On Wed, Mar 21, 2018 at 11:02 AM, Rodrigo <[hidden email]> wrote:
My proposal is to keep it simple and implement the if-assignment `if(
const o = ...; ! o ) { ... }` mimicking the `for(;;)` assignment
behavior.

Fair enough.  If the assignment is separate from the condition, then none of that matters.
That question only pertained to let/const declarations used for their value.

That way we can scope a variable to the `if` block and we can do that
*separately* from assignment.

Assigning and comparing at the same time opens up all sort of oddities
as the variable transitions from lvalue to comparison operand. This
already exists in the language and is definitely not good practice.

`if.value`, as proposed earlier is a bombshell similar to `this`,
which could easily get scrambled with the introduction of additional
`if` blocks.

The beauty of `if(;)` is that it makes scope blocks possible while
avoiding the asymmetric behavior caused by assigning and comparing in
one go.

        if( let people=getTeamArray(); people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }

IIUC, it sounds like the right side could be syntactic sugar for the left side.
If that's right, what about the left side warrants new syntax to enable the right?
 

CurrentProposed
  {
       let people = getTeamArray();
       if( people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }
  }
   if( let people = getTeamArray(); people.length > 2 ) {
       console.log("it's a crowd", people.join(','));
   }
   else if( people.length == 2 ) {
       console.log("just a pair");
   }
   else if( people.length == 1 {
       console.log("solo");
   }
   else {
       console.log("none");
   }

I can imagine that it might be nice when used later in an else-if chain:

if (c0) {
  ...
} else (let x = v1, c1(x)) {
  ...
} else ...

vs

if (c0) {
  ...
} else {
  let x = v1;
  if (c1(x)) {
    ...
  } else ...
}

Can you point at any particularly tricky code that could be simplified by this?

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

kai zhu
how is any of this less-confusing than a simple style-guide of pre-declaring all variables @ the beginning of a function?
again, there’s zero legitimate reason why javascript even needs block-level scoping of variables (and arguing because other languages have it is not a reason).  you're just creating more needless javascript style-guide variance that further confuses your team-members / project-successor.

```
/*jslint
    bitwise: true,
    browser: true,
    maxerr: 8,
    maxlen: 100,
    node: true,
    nomen: true,
    regexp: true,
    stupid: true
*/
(function () {
    'use strict';
    // es5 best-practice of declaring all variables at beginning of function,
    // and runtime-checked by 'use strict' pragma
    var bar,
        c0,
        c1,
        foo,
        getTeamArray,
        people,
        v1,
        xx,
        yy;



    getTeamArray = function () {
        return [1, 2, 3];
    };
    people = getTeamArray();
    if (people.length > 2) {
        console.log("it's a crowd", people.join(','));
    } else if (people.length === 2) {
        console.log("just a pair");
    } else if (people.length === 1) {
        console.log("solo");
    } else {
        console.log("none");
    }
    // output: it's a crowd 1,2,3



    bar = function () {
        return 0;
    };
    foo = function () {
        return 50;
    };
    (function () {
        xx = foo();
        if (xx < 50) {
            console.log(xx); // yy is not available here
            return;
        }
        yy = bar();
        if (yy > 0) {
            console.log(yy);
            return;
        }
        // else
        console.log(xx, yy);
    }());
    // output: 50 0



    c0 = null;
    c1 = function (xx) {
        return xx;
    };
    v1 = false;
    // 'unset' xx
    xx = undefined;
    (function () {
        if (c0) {
            console.log(c0); // xx is not available here
            return;
        }
        xx = v1;
        if (c1(xx)) {
            console.log(xx);
            return;
        }
        // else
        console.log(c0, xx);
    }());
    // output: null false
}());
```

On Mar 22, 2018, at 1:56 AM, Mike Samuel <[hidden email]> wrote:



On Wed, Mar 21, 2018 at 11:02 AM, Rodrigo <[hidden email]> wrote:
My proposal is to keep it simple and implement the if-assignment `if(
const o = ...; ! o ) { ... }` mimicking the `for(;;)` assignment
behavior.

Fair enough.  If the assignment is separate from the condition, then none of that matters.
That question only pertained to let/const declarations used for their value.

That way we can scope a variable to the `if` block and we can do that
*separately* from assignment.

Assigning and comparing at the same time opens up all sort of oddities
as the variable transitions from lvalue to comparison operand. This
already exists in the language and is definitely not good practice.

`if.value`, as proposed earlier is a bombshell similar to `this`,
which could easily get scrambled with the introduction of additional
`if` blocks.

The beauty of `if(;)` is that it makes scope blocks possible while
avoiding the asymmetric behavior caused by assigning and comparing in
one go.

        if( let people=getTeamArray(); people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }

IIUC, it sounds like the right side could be syntactic sugar for the left side.
If that's right, what about the left side warrants new syntax to enable the right?
 

CurrentProposed
  {
       let people = getTeamArray();
       if( people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }
  }
   if( let people = getTeamArray(); people.length > 2 ) {
       console.log("it's a crowd", people.join(','));
   }
   else if( people.length == 2 ) {
       console.log("just a pair");
   }
   else if( people.length == 1 {
       console.log("solo");
   }
   else {
       console.log("none");
   }

I can imagine that it might be nice when used later in an else-if chain:

if (c0) {
  ...
} else (let x = v1, c1(x)) {
  ...
} else ...

vs

if (c0) {
  ...
} else {
  let x = v1;
  if (c1(x)) {
    ...
  } else ...
}

Can you point at any particularly tricky code that could be simplified by this?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Sebastian Malton
Because block-level scoping is a very good way to avoid certain bugs and is easier to reason about. Especially when considering project successors. 

Now, you cannot say that arguing that other languages have it is irrelevant. That is not the case because they have decided to so for good software engineering reasons. They could have easily had everything functionally scoped too but they don't. 

And bringing up your opinion that we don't need a feature that is currently in the spec is not helpful in this context because it is never going away, that would be an insane breaking change. 


*rant over*

Otherwise, the for(;;) syntax seems like the best and most intuitive. Especially for how that would work actually. 

Question though, would the variable be available in an else or else-if block

Sebastian Malton

Sent: March 21, 2018 1:21 PM
Subject: Re: Proposal: if variable initialization

how is any of this less-confusing than a simple style-guide of pre-declaring all variables @ the beginning of a function?
again, there’s zero legitimate reason why javascript even needs block-level scoping of variables (and arguing because other languages have it is not a reason).  you're just creating more needless javascript style-guide variance that further confuses your team-members / project-successor.

```
/*jslint
    bitwise: true,
    browser: true,
    maxerr: 8,
    maxlen: 100,
    node: true,
    nomen: true,
    regexp: true,
    stupid: true
*/
(function () {
    'use strict';
    // es5 best-practice of declaring all variables at beginning of function,
    // and runtime-checked by 'use strict' pragma
    var bar,
        c0,
        c1,
        foo,
        getTeamArray,
        people,
        v1,
        xx,
        yy;



    getTeamArray = function () {
        return [1, 2, 3];
    };
    people = getTeamArray();
    if (people.length > 2) {
        console.log("it's a crowd", people.join(','));
    } else if (people.length === 2) {
        console.log("just a pair");
    } else if (people.length === 1) {
        console.log("solo");
    } else {
        console.log("none");
    }
    // output: it's a crowd 1,2,3



    bar = function () {
        return 0;
    };
    foo = function () {
        return 50;
    };
    (function () {
        xx = foo();
        if (xx < 50) {
            console.log(xx); // yy is not available here
            return;
        }
        yy = bar();
        if (yy > 0) {
            console.log(yy);
            return;
        }
        // else
        console.log(xx, yy);
    }());
    // output: 50 0



    c0 = null;
    c1 = function (xx) {
        return xx;
    };
    v1 = false;
    // 'unset' xx
    xx = undefined;
    (function () {
        if (c0) {
            console.log(c0); // xx is not available here
            return;
        }
        xx = v1;
        if (c1(xx)) {
            console.log(xx);
            return;
        }
        // else
        console.log(c0, xx);
    }());
    // output: null false
}());
```

On Mar 22, 2018, at 1:56 AM, Mike Samuel <[hidden email]> wrote:



On Wed, Mar 21, 2018 at 11:02 AM, Rodrigo <[hidden email]> wrote:
My proposal is to keep it simple and implement the if-assignment `if(
const o = ...; ! o ) { ... }` mimicking the `for(;;)` assignment
behavior.

Fair enough.  If the assignment is separate from the condition, then none of that matters.
That question only pertained to let/const declarations used for their value.

That way we can scope a variable to the `if` block and we can do that
*separately* from assignment.

Assigning and comparing at the same time opens up all sort of oddities
as the variable transitions from lvalue to comparison operand. This
already exists in the language and is definitely not good practice.

`if.value`, as proposed earlier is a bombshell similar to `this`,
which could easily get scrambled with the introduction of additional
`if` blocks.

The beauty of `if(;)` is that it makes scope blocks possible while
avoiding the asymmetric behavior caused by assigning and comparing in
one go.

        if( let people=getTeamArray(); people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }

IIUC, it sounds like the right side could be syntactic sugar for the left side.
If that's right, what about the left side warrants new syntax to enable the right?
 

CurrentProposed
  {
       let people = getTeamArray();
       if( people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }
  }
   if( let people = getTeamArray();  people.length > 2 ) {
       console.log("it's a crowd", people.join(','));
   }
   else if( people.length == 2 ) {
       console.log("just a pair");
   }
   else if( people.length == 1 {
       console.log("solo");
   }
   else {
       console.log("none");
   }

I can imagine that it might be nice when used later in an else-if chain:

if (c0) {
  ...
} else (let x = v1, c1(x)) {
  ...
} else ...

vs

if (c0) {
  ...
} else {
  let x = v1;
  if (c1(x)) {
    ...
  } else ...
}

Can you point at any particularly tricky code that could be simplified by this?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Christopher Thorn
In reply to this post by kai zhu
This is just trolling that seems intended to derail the discussion.

On Wed, Mar 21, 2018 at 10:21 AM, kai zhu <[hidden email]> wrote:
how is any of this less-confusing than a simple style-guide of pre-declaring all variables @ the beginning of a function?
again, there’s zero legitimate reason why javascript even needs block-level scoping of variables (and arguing because other languages have it is not a reason).  you're just creating more needless javascript style-guide variance that further confuses your team-members / project-successor.

```
/*jslint
    bitwise: true,
    browser: true,
    maxerr: 8,
    maxlen: 100,
    node: true,
    nomen: true,
    regexp: true,
    stupid: true
*/
(function () {
    'use strict';
    // es5 best-practice of declaring all variables at beginning of function,
    // and runtime-checked by 'use strict' pragma
    var bar,
        c0,
        c1,
        foo,
        getTeamArray,
        people,
        v1,
        xx,
        yy;



    getTeamArray = function () {
        return [1, 2, 3];
    };
    people = getTeamArray();
    if (people.length > 2) {
        console.log("it's a crowd", people.join(','));
    } else if (people.length === 2) {
        console.log("just a pair");
    } else if (people.length === 1) {
        console.log("solo");
    } else {
        console.log("none");
    }
    // output: it's a crowd 1,2,3



    bar = function () {
        return 0;
    };
    foo = function () {
        return 50;
    };
    (function () {
        xx = foo();
        if (xx < 50) {
            console.log(xx); // yy is not available here
            return;
        }
        yy = bar();
        if (yy > 0) {
            console.log(yy);
            return;
        }
        // else
        console.log(xx, yy);
    }());
    // output: 50 0



    c0 = null;
    c1 = function (xx) {
        return xx;
    };
    v1 = false;
    // 'unset' xx
    xx = undefined;
    (function () {
        if (c0) {
            console.log(c0); // xx is not available here
            return;
        }
        xx = v1;
        if (c1(xx)) {
            console.log(xx);
            return;
        }
        // else
        console.log(c0, xx);
    }());
    // output: null false
}());
```

On Mar 22, 2018, at 1:56 AM, Mike Samuel <[hidden email]> wrote:



On Wed, Mar 21, 2018 at 11:02 AM, Rodrigo <[hidden email]> wrote:
My proposal is to keep it simple and implement the if-assignment `if(
const o = ...; ! o ) { ... }` mimicking the `for(;;)` assignment
behavior.

Fair enough.  If the assignment is separate from the condition, then none of that matters.
That question only pertained to let/const declarations used for their value.

That way we can scope a variable to the `if` block and we can do that
*separately* from assignment.

Assigning and comparing at the same time opens up all sort of oddities
as the variable transitions from lvalue to comparison operand. This
already exists in the language and is definitely not good practice.

`if.value`, as proposed earlier is a bombshell similar to `this`,
which could easily get scrambled with the introduction of additional
`if` blocks.

The beauty of `if(;)` is that it makes scope blocks possible while
avoiding the asymmetric behavior caused by assigning and comparing in
one go.

        if( let people=getTeamArray(); people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }

IIUC, it sounds like the right side could be syntactic sugar for the left side.
If that's right, what about the left side warrants new syntax to enable the right?
 

CurrentProposed
  {
       let people = getTeamArray();
       if( people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }
  }
   if( let people = getTeamArray(); people.length > 2 ) {
       console.log("it's a crowd", people.join(','));
   }
   else if( people.length == 2 ) {
       console.log("just a pair");
   }
   else if( people.length == 1 {
       console.log("solo");
   }
   else {
       console.log("none");
   }

I can imagine that it might be nice when used later in an else-if chain:

if (c0) {
  ...
} else (let x = v1, c1(x)) {
  ...
} else ...

vs

if (c0) {
  ...
} else {
  let x = v1;
  if (c1(x)) {
    ...
  } else ...
}

Can you point at any particularly tricky code that could be simplified by this?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Jerry Schulteis
In reply to this post by Rodrigo
I have used the desugared version and found that what seemed obvious to me, that the purpose of the block was to limit the scope, was not obvious to other developers on  my team.

If this proposal moves forward I think it should include switch and while in addition to if.


On Wednesday, March 21, 2018, 11:56:08 AM CDT, Mike Samuel <[hidden email]> wrote:

[...]
IIUC, it sounds like the right side could be syntactic sugar for the left side.
If that's right, what about the left side warrants new syntax to enable the right?

CurrentProposed
  {
       let people = getTeamArray();
       if( people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }
  }
   if( let people = getTeamArray(); people.length > 2 ) {
       console.log("it's a crowd", people.join(','));
   }
   else if( people.length == 2 ) {
       console.log("just a pair");
   }
   else if( people.length == 1 {
       console.log("solo");
   }
   else {
       console.log("none");
   }
[...]
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

kai zhu
In reply to this post by Christopher Thorn
i'm not trolling. unlike javascript, most other languages deal near exclusively with blocking-code, which is only applicable to low-level library-code in javascript (that pretty much anyone can write).  at higher-level integration-stuff dealing with non-blocking io, these blocking-code design-patterns from other languages are pretty-much useless.  like say … *block-level scoping*, because it doesn’t mix well with closures, which are heavily used in integration-level javascript to keep track of states for non-blocking code.

e.g.
```
/*jslint
    bitwise: true,
    browser: true,
    maxerr: 8,
    maxlen: 200,
    node: true,
    nomen: true,
    regexp: true,
    stupid: true
*/
(function () {
    'use strict';

    var chunkList, request, response, timerTimeout;
    chunkList = [];
    // auto-timeout and cleanup closure-vars request and response after 30000 ms
    timerTimeout = setTimeout(function () {
        try {
            request.destroy();
        } catch (ignore) {
        }
        try {
            response.destroy();
        } catch (ignore) {
        }
        console.error('timeout error after 30000 ms');
    }, 30000);
    request = require('https').request(
        require('url').parse('https://www.example.com'),
        function (_response) {
            response = _response;
            response.on('data', function (chunk) {
                // append chunk to closure-var chunkList
                chunkList.push(chunk);
            });
            response.on('end', function () {
                // print closure-var chunkList to stdout
                console.log(Buffer.concat(chunkList).toString());
                // cancel closure-var timerTimeout,
                // after request successfully completes
                clearTimeout(timerTimeout);
            });
        }
    );
    request.end();



/*
output:

<!doctype html>
<html>
<head>
    <title>Example Domain</title>
...
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.</p>
    <p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
*/
}());
```

On Mar 22, 2018, at 2:31 AM, Christopher Thorn <[hidden email]> wrote:

This is just trolling that seems intended to derail the discussion.

On Wed, Mar 21, 2018 at 10:21 AM, kai zhu <[hidden email]> wrote:
how is any of this less-confusing than a simple style-guide of pre-declaring all variables @ the beginning of a function?
again, there’s zero legitimate reason why javascript even needs block-level scoping of variables (and arguing because other languages have it is not a reason).  you're just creating more needless javascript style-guide variance that further confuses your team-members / project-successor.

```
/*jslint
    bitwise: true,
    browser: true,
    maxerr: 8,
    maxlen: 100,
    node: true,
    nomen: true,
    regexp: true,
    stupid: true
*/
(function () {
    'use strict';
    // es5 best-practice of declaring all variables at beginning of function,
    // and runtime-checked by 'use strict' pragma
    var bar,
        c0,
        c1,
        foo,
        getTeamArray,
        people,
        v1,
        xx,
        yy;



    getTeamArray = function () {
        return [1, 2, 3];
    };
    people = getTeamArray();
    if (people.length > 2) {
        console.log("it's a crowd", people.join(','));
    } else if (people.length === 2) {
        console.log("just a pair");
    } else if (people.length === 1) {
        console.log("solo");
    } else {
        console.log("none");
    }
    // output: it's a crowd 1,2,3



    bar = function () {
        return 0;
    };
    foo = function () {
        return 50;
    };
    (function () {
        xx = foo();
        if (xx < 50) {
            console.log(xx); // yy is not available here
            return;
        }
        yy = bar();
        if (yy > 0) {
            console.log(yy);
            return;
        }
        // else
        console.log(xx, yy);
    }());
    // output: 50 0



    c0 = null;
    c1 = function (xx) {
        return xx;
    };
    v1 = false;
    // 'unset' xx
    xx = undefined;
    (function () {
        if (c0) {
            console.log(c0); // xx is not available here
            return;
        }
        xx = v1;
        if (c1(xx)) {
            console.log(xx);
            return;
        }
        // else
        console.log(c0, xx);
    }());
    // output: null false
}());
```

On Mar 22, 2018, at 1:56 AM, Mike Samuel <[hidden email]> wrote:



On Wed, Mar 21, 2018 at 11:02 AM, Rodrigo <[hidden email]> wrote:
My proposal is to keep it simple and implement the if-assignment `if(
const o = ...; ! o ) { ... }` mimicking the `for(;;)` assignment
behavior.

Fair enough.  If the assignment is separate from the condition, then none of that matters.
That question only pertained to let/const declarations used for their value.

That way we can scope a variable to the `if` block and we can do that
*separately* from assignment.

Assigning and comparing at the same time opens up all sort of oddities
as the variable transitions from lvalue to comparison operand. This
already exists in the language and is definitely not good practice.

`if.value`, as proposed earlier is a bombshell similar to `this`,
which could easily get scrambled with the introduction of additional
`if` blocks.

The beauty of `if(;)` is that it makes scope blocks possible while
avoiding the asymmetric behavior caused by assigning and comparing in
one go.

        if( let people=getTeamArray(); people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }

IIUC, it sounds like the right side could be syntactic sugar for the left side.
If that's right, what about the left side warrants new syntax to enable the right?
 

CurrentProposed
  {
       let people = getTeamArray();
       if( people.length > 2 ) {
           console.log("it's a crowd", people.join(','));
       }
       else if( people.length == 2 ) {
           console.log("just a pair");
       }
       else if( people.length == 1 {
           console.log("solo");
       }
       else {
           console.log("none");
       }
  }
   if( let people = getTeamArray(); people.length > 2 ) {
       console.log("it's a crowd", people.join(','));
   }
   else if( people.length == 2 ) {
       console.log("just a pair");
   }
   else if( people.length == 1 {
       console.log("solo");
   }
   else {
       console.log("none");
   }

I can imagine that it might be nice when used later in an else-if chain:

if (c0) {
  ...
} else (let x = v1, c1(x)) {
  ...
} else ...

vs

if (c0) {
  ...
} else {
  let x = v1;
  if (c1(x)) {
    ...
  } else ...
}

Can you point at any particularly tricky code that could be simplified by this?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Mike Samuel
In reply to this post by Sebastian Malton


On Wed, Mar 21, 2018 at 1:27 PM, Sebastian Malton <[hidden email]> 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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

Mike Samuel
In reply to this post by kai zhu
TIL

On Wed, Mar 21, 2018 at 2:29 PM, kai zhu <[hidden email]> wrote:
/*jslint
    stupid: true 
*/ 

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: if variable initialization

kai zhu
In reply to this post by Mike Samuel
@mike yes that’s true, but issues with blocking-code javascript data-structures/algorithms are rarely the reason web-projects fail.  they fail largely due to unresolvable integration-level io/workflow issues (that are unique only to javascript).  block-scoping fixes the insignificant former, while exacerbating the more pressing latter, by encouraging people to pollute variable-declarations all-over-the-place; making it harder to discern-and-debug which ones are critical io-related closure-variables and which ones are not.

data-structure and algorithmic coding-skills are rarely all that useful in javascript (just throw sqlite3 at it and it will likely go away).  integration-level debugging-skills (and knowledge of which coding design-patterns to employ to make io easier to debug) are far more valuable and correlable to successfully shipping a web-project.

On Mar 22, 2018, at 3:47 AM, Mike Samuel <[hidden email]> wrote:



On Wed, Mar 21, 2018 at 1:27 PM, Sebastian Malton <[hidden email]> 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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
123