Brendan Eich (2014-08-01T18:54:54.000Z)
The general problem is that body blocks are not exactly blocks, due to 
legacy cruft -- and this legacy cannot be separated from 'let' ideals 
because we want programmers to refactor from 'var' to 'let'.

So we must give greater weight (compared to the ideal case of a body 
block just being a block) to refactoring hazards that result in silent 
but deadly bugs rather than early errors.

In particular,

function f(a) {
   ... // TDZ
   let a = ...;
   ...
}

and

function g() {
   try {
     ...
   } catch (e) {
     ... // TDZ
     let e = ...;
     ...
   }
}

should be early errors because there's no useful shadowing going on with 
'let' -- the TDZ means the outer binding cannot be used in the commented 
places -- but any prior version using 'var' would have worked and 
possibly allowed (coverage-dependent) uses of the "outer" (in catch's 
case, var hoists across the catch head in sloppy code; in the parameter 
case there's only ever one 'a' binding) use in the TDZ.

So an early error does no actual harm in either case, and helps avoid 
bugs slipping past incomplete test coverage.

HTH,

/be

Brendan Eich wrote:
> Andreas Rossberg wrote:
>> I think this subtle discrepancy is both unfortunate and unnecessary
>> [1]. Moreover, with ES7 do expressions, I would like it to hold that
>>
>>    (...) =>  {...}    ≡    (...) =>  do {...}
>
> I channeled you as best I could, and Dmitry Lomov kindly channeled you 
> on this point, but more than a few TC39ers objected that the left 
> arrow function, with a body block instead of a body expression, has 
> different semantics already, ignoring whether let x; in the body block 
> could shadow a parameter x. First, 'return' is the only way to return 
> a result in the left example, whereas thanks to do-expression being an 
> expression, the completion value (reformed) of the right ... is the 
> return value, even without 'return'.
>
> I wanted to pass this back ASAP. More is being recorded in the meeting 
> notes, but here you go. We'll keep channeling you as best we can!
>
> /be
domenic at domenicdenicola.com (2014-08-22T21:23:53.892Z)
The general problem is that body blocks are not exactly blocks, due to 
legacy cruft -- and this legacy cannot be separated from 'let' ideals 
because we want programmers to refactor from 'var' to 'let'.

So we must give greater weight (compared to the ideal case of a body 
block just being a block) to refactoring hazards that result in silent 
but deadly bugs rather than early errors.

In particular,

```js
function f(a) {
   ... // TDZ
   let a = ...;
   ...
}
```

and

```js
function g() {
   try {
     ...
   } catch (e) {
     ... // TDZ
     let e = ...;
     ...
   }
}
```

should be early errors because there's no useful shadowing going on with 
'let' -- the TDZ means the outer binding cannot be used in the commented 
places -- but any prior version using 'var' would have worked and 
possibly allowed (coverage-dependent) uses of the "outer" (in catch's 
case, var hoists across the catch head in sloppy code; in the parameter 
case there's only ever one 'a' binding) use in the TDZ.

So an early error does no actual harm in either case, and helps avoid 
bugs slipping past incomplete test coverage.