The curious incident of the semicolon at the newline
April 23, 2012  

Once again, someone is wrong about syntax on the Internet! As an author of several papers on parsing, I can’t resist the spectacle.

The fight is over the following snippet of JavaScript:

    !isActive && $parent.toggleClass('open')

Note the semicolon after clearMenus(). a href=""As Holmes would say, what is curious about this semicolon is that it does nothing at the newline. That is, as far as the JavaScript parser is concerned, it might as well be omitted:

    !isActive && $parent.toggleClass('open')

When JavaScript parses this, it notices that a semicolon is missing after clearMenus(), but acts as if it were not missing. So the variant without the semicolon parses just fine.

The problem is that while the parser produces the very same result for these two snippets, other tools do not. In particular, a href=""JSMin was transforming the syntactically-correct second snippet into code that would not parse.

I’m not going to weigh in on whether this is a bug in JSMin, or whether the code in question should be changed—a href=""the debate on those issues, and their resolution, is already entertaining enough.

What I will say is that JSMin can never live up to this blurb from its own README:

JSMin is a filter that omits or modifies some characters. This does not change the behavior of the program that it is minifying.

Douglas Crockford, JSMin’s author, provides several counterexamples himself later in the same README, so he knows this statement is false. What I am stating, however, is much stronger:

All filters that omit or modify some characters must change the behavior of some JavaScript programs.

To see this, just consider that JavaScript programs are typically run in browsers as part of a web page, where they have access to their own text via the DOM. A program that can examine its own text can alter its behavior if its text has been altered.

This may seem like a pedantic edge case of an obscure program. The truth is, what is true for this obscure program is also true for every programming tool you have ever used, including every compiler. None of these tools are semantics preserving. The “pedantic edge case” may be different for different tools, but I guarantee you, they all have one.