In strict mode you can because you can statically determine if eval is present. If it isn't, it is trivial to determine if it is written to after initialization.
Otherwise it has the same issues as const (is there a temporal dead zone violation?)
You're not doing static analysis - you're doing dynamic analysis and speculation. But this has the downsides I said - it's more complicated, it takes more time, etc.
What speculation? If you have a "let" in some lexical scope, AND this is strict mode, AND there are no calls to eval in that scope, AND there are no assignments within that scope... how is that different from const?
I can understand why in a JavaScript engine there may be plenty of other concerns and it may be completely reasonable to not do the analysis, but in the common case it should (at least) be something you could do just by walking the AST, if you so desired, without even knowing the surrounding code.
> Speculating that a debugger is not attached and modifying local variables, is one example.
A debugger can do anything. You can't outthink a debugger and shouldn't try.
> Yes that’s why it’s speculation - handle the common cases and speculate away the uncommon cases.
Speculation is when you guess and need to have a guard in case the guess is wrong. They're describing a situation where it can't be wrong and you wouldn't need to speculate.
> You'd get extremely slow code with this approach!
You must be interpreting that differently than I meant it. The approach I'm suggesting is "pretend debuggers don't exist when optimizing". It gives you the fast code.
A debugger can break any assumption you make. Even unoptimized code could crash if a debugger messes with it. The fear of a debugger should never make you decide not to do an optimization.
How would you use a guard if you want to deoptimize because a debugger attached? You'd have to have a guard between each instruction, and even then it might not be enough.
> Yes, you're guessing that nobody will attach a debugger and you're guarding that no debugger has been attached. That guard is usually implicit.
> So you deoptimise when someone starts debugging.
If an "implicit" guard means "we'll have a function the debugger calls, telling us to redo the compilation", then that's not something you need to do dynamic analysis for, and it doesn't make your compilation more complicated. You don't "speculate away" that case unless you're using the word "speculate" to include "completely ignore for now, without even a guard", which I didn't think fell under that umbrella. Does it?
> It can be wrong... if someone's using a debugger.
It's not wrong. A debugger can make 2+2 be 5. Debuggers don't follow any rules, but that doesn't mean your compiler should try (and inevitably fail) to make code that works in a world where no rules exist.
Otherwise it has the same issues as const (is there a temporal dead zone violation?)