Oliver Hunt (2014-01-30T16:25:22.000Z)
On Jan 30, 2014, at 8:07 AM, Dean Landolt <dean at deanlandolt.com> wrote:

> 
> 
> 
> On Thu, Jan 30, 2014 at 10:59 AM, John Barton <johnjbarton at google.com> wrote:
> 
> 
> 
> On Thu, Jan 30, 2014 at 7:54 AM, Brendan Eich <brendan at mozilla.com> wrote:
> John Lenz wrote:
> Generally, I've always thought of:
> 
> "if (x) ..." as equivalent to "if (x) { ... }"
> 
> let and const (and class) are block-scoped. {...} in your "if (x) {...}" is a block. An unbraced consequent is not a block, and you can't have a "conditional let binding".
> 
> The restriction avoids nonsense such as
> 
> let x = 0; { if (y) let x = 42; alert(x); }
> 
> What pray tell is going on here, in your model?
> 
> I'm with John: the alert should say 0 and I can't see why that is not obvious.
> 
> 
> It's not obvious at all -- what happens when you drop the initial `let x = 0;` and you just have `{ if (y) let x = 42; alert(x); }` -- now what happens? Is x declared or not?
> 
> To my mind `if (y) let x = 42;` reads like it's own 1-line noop block -- at least, that's what I'd expect of the scope. So while it could be allowed in that sense, it'd only serve as a footgun when y is true.

This is exactly foot gun the language restriction is intended to avoid.

Most modern [Obj-]C[++] will warn on this (well, s/let/int/)

You might be getting confused because of the bizarro var hoisting semantics of var

if (y) let x = “nope"; alert(x)

Results in an unusable binding of x, and so this would throw (the foot gun occurs if you’re shadowing x, that’s another shadow that i think C compilers will warn on), e.g..
y = true; let x = “whoops”; if (y) let x = “nope"; alert(x) // “whoops"

The var case

y = true; var x = “whoops”; if (y) var x = “nope"; alert(x); // “nope"

is actually interpreted as

var x; y= true; x = “whoops”; if (y) x = “nope”; alert(x); // “nope"

That craziness is the whole point of block scoping let.  More interestingly

if (window.SomeCrazyDomFeature) var foo = true;

is a common web idiom as it brings foo into scope for everything, so makes later "if (foo) “ statements safe.  Anyone trying to do this with a |let| would get incorrect (from their PoV) behaviour.  Again that’s why we error out.

Give that this is the behaviour of every other block scoped language i don’t see why this is confusing.

—Oliver

> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140130/2763a7f5/attachment-0001.html>
domenic at domenicdenicola.com (2014-02-04T21:34:10.441Z)
On Jan 30, 2014, at 8:07 AM, Dean Landolt <dean at deanlandolt.com> wrote:

> It's not obvious at all -- what happens when you drop the initial `let x = 0;` and you just have `{ if (y) let x = 42; alert(x); }` -- now what happens? Is x declared or not?
> 
> To my mind `if (y) let x = 42;` reads like it's own 1-line noop block -- at least, that's what I'd expect of the scope. So while it could be allowed in that sense, it'd only serve as a footgun when y is true.

This is exactly foot gun the language restriction is intended to avoid.

Most modern [Obj-]C[++] will warn on this (well, s/let/int/)

You might be getting confused because of the bizarro var hoisting semantics of var

```js
if (y) let x = “nope"; alert(x)
```

Results in an unusable binding of x, and so this would throw (the foot gun occurs if you’re shadowing x, that’s another shadow that i think C compilers will warn on), e.g..

```js
y = true; let x = “whoops”; if (y) let x = “nope"; alert(x) // “whoops"
```

The var case

```js
y = true; var x = “whoops”; if (y) var x = “nope"; alert(x); // “nope"
```

is actually interpreted as

```js
var x; y= true; x = “whoops”; if (y) x = “nope”; alert(x); // “nope"
```

That craziness is the whole point of block scoping let.  More interestingly

```js
if (window.SomeCrazyDomFeature) var foo = true;
```

is a common web idiom as it brings foo into scope for everything, so makes later "if (foo) “ statements safe.  Anyone trying to do this with a |let| would get incorrect (from their PoV) behaviour.  Again that’s why we error out.

Give that this is the behaviour of every other block scoped language i don’t see why this is confusing.