Younger I was a dogmatic developer blindly enforcing the IT gurus’ dogma, later I’ve become more pragmatic preferring code readability and maintainability.
But in some rare corner cases omitting a semicolon can completely change the way the compiler interprets the code.
Hopefully, it will cause a compilation error, and in the worst case a hidden bug hard to track.
In this article, I describe one of these corner cases.
A simple code
var evens = , odds =  var n = 123 console.log("n is %s", n % 2 === 0 ? 'even' : 'odd') (n % 2 === 0 ? evens : odds).push(n)
n is even it is added to the
evens array, otherwise to the
A strange error
But compiling it raise a
(n % 2 === 0 ? evens : odds).push(n)
TypeError: console.log(…) is not a function
at Object. (C:\Temp\test.js:7:1)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:754:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
The error is telling that we cannot call the return value of
console.log as it is not a function!
Apparently, the compiler has misunderstood our intent.
What the compiler sees
Indeed here is how the compiler interprets the last lines:
console.log("n is %s", n % 2 === 0 ? 'even' : 'odd')(n % 2 === 0 ? evens : odds).push(n)
Not the same meaning at all, here the call to the return value of
console.log is obvious.
Clarifying our intent
To help the compiler understand that we have two separate instructions we must separate them with a semicolon:
console.log("n is %s", n % 2 === 0 ? 'even' : 'odd'); (n % 2 === 0 ? evens : odds).push(n)
Now the code runs as expected pushing
n to the relevant array.
Let’s say this is what makes it somehow flavorful. 😉