Transitioning to strict mode

David Bruant bruant.d at gmail.com
Thu Feb 21 09:12:35 PST 2013


Le 18/02/2013 23:29, Claus Reinke a écrit :
>>> Out of curiosity, what does your favorite test coverage tool report 
>>> for the source below? And what does it report when you comment
>>> out the directive?
>> :-p Ok, there are exceptions if your code depends on semantic changes 
>> described in the third section of the article (dynamic 
>> this/eval/arguments).
>> That's you case with how you define isStrict (dynamic this)
>> So: if your code does *not* depend on semantic changes, all instances 
>> of setting to an undeclared variable will be caught.
>
> Just wanted to shake your faith in testing :-) The example code might
> look unlikely, but real code is more complex and might evolve nasty
> behavior without such artificial tuning.
>
> You still need more than statement or branch coverage. Otherwise,
> we might get 100% "coverage" while missing edge cases
>
>    function raise() {
>      "use strict";
>      if( Math.random()>0.5 || (Math.random()<0.5) && (variable = 0)) 
>        console.log(true);
>      else
>        console.log(false);
>    }
>
>    raise();
>    raise();
>    raise(); // adjust probabilities and call numbers until we get
>                // "reliable" 100% branch coverage with no errors; then
>                // wait for the odd assignment to happen anyway, in
>                // production, not reproducably
There is no "reliable 100% coverage" in this case. The coverage I guess 
is... probabilistic?

> Throwing or not throwing Reference Errors is also a semantics change, 
> and since errors can be caught, we can react to their presence/absence,
> giving another avenue for accidental semantics changes.
I agree it's a semantic change, but it's one that's special in the 
development workflow. The common practice is to fix code that throws, 
whatever that means.
non-directly-throwing semantic changes require a different kind of 
attention and testing.
I understand errors can be caught by a try-catch placed for other 
reasons, but whoever cares about transitioning to strict mode will be 
careful to this kind of issues.

> Undeclared variables are likely to be unintended, and likely to lead to
> bugs, but they might also still let the code run successfully to 
> completion where strict mode errors do or don't, depending on 
> circumstances.
I agree. The goal when transitioning to strict mode is also to preserve 
the semantics of the original code. I've tried to provide examples of 
how to fix common errors. For the undeclared variable case, I've 
explained how to legitimately assign a global variable if that's what 
was really intended. This way, there is a quick fix that preserves the 
semantics.
Other fixes for all the error cases are welcome as contributions.

> Testing increases confidence (sometimes too much so) but cannot
> prove correctness, only the absence of selected errors.
I fully agree.

> What I'd like to understand is why likely static scoping problems
> should lead to a runtime error, forcing the dependence on testing.
> If they'd lead to compile time errors (for strict code), there'd be no 
> chance of missing them on the developer engine, independent of 
> incomplete test suite or ancient customer engines. Wouldn't that 
> remove one of the concerns against using strict mode? What am I missing?
I guess it's too late now for ES5 strict mode.
What was the rationale behind making it a runtime error?

I think there were plans to make it a compile-time error... was it with 
the ES6 opt-in? :-s
Can it be retrofit in new syntax which are their own opt-in (module, 
class...)?

David


More information about the es-discuss mailing list