When it comes to the use of semicolons in JavaScript or TypeScript, it is difficult to know where to begin. The sheer magnitude of the tripe and bile that has been spilled over this optional bit of syntactic sugar is astonishing.
So let’s settle this shit once and for all.
Semicolons are optional in JavaScript except for a few corner cases.
The people who claim that they are “not optional” are utterly full of shit.
And here’s the proof: I can write JavaScript without semicolons—except for those very rare corner cases I’ve already mentioned—and it will work in node, deno, and every modern browser.
Quod. Erat. Demonstrandum.
So why the fuck do so many arrogant shits keep telling me that they are not optional and that I must use them or my code will be “dangerous”?
The operative word in that interrogatory is “arrogant”: these are people who think that they are smarter than everyone else and that therefore whatever they believe is “right”, hence anyone who disagrees with them is an idiot.
Usually, however, they simply let loose their rabid fanboys to bash the heathens who worship not the semicolon god.
I don’t tell you how to code
So why the fuck do you keep telling me how to code? I’ve written almost exclusively JavaScript and TypeScript for more than a decade now, and I stopped using semicolons almost that long ago.
Ten fucking years and at least a million lines of code without semicolons and not a single failure caused by a missing semicolon.
Where is any evidence at all of this danger? There is none. They made it up.
But the most amazing part of all this is that I’ve never met anyone who doesn’t use semicolons in JS or TS who also insists that everyone else stop using them. They just want the ability to leave them out. Why not? They’re optional.
What is so unreasonable about that? To the semicolon fascists, everything apparently. We no-semicolon folks are ruining the Internet and maybe Christmas, too.
The dipshittery of Deno
I have been a big proponent of Deno almost since day one. I waited with bated breath for it to be useable. I was among the earliest of adopters. I’m so eager that I gave up on Prettier and switched to Dprint even in my node.js code.
Then I discovered while reading an issue in the Deno repo that when Deno uses Dprint for its deno
fmt
command, it does not permit one to set semicolons to ASI. That Dprint option is blocked.
If Dprint allows it, why would you block it? Many others chimed in with their dismay. Why? Why? Why?
And then in a classic example of everything that is wrong with open source and the remarkable contempt that many OSS folks have for their supporters (!), someone by the username of lucacasonato posted this:
This discussion is the perfect example why we will not be introducing additional options to the built in formatter. All source code written for Deno should use the same formatting options for consistency, and to reduce this kind of discussion. In our eyes ecosystem consistency is much more important than opinions of individuals. This is also why we limit configuration options of the runtime and type checker as much as we do.
And then, in the classic manner of OSS pricks everywhere, he closed the discussion once he’d had the final word. Fuck you and goodbye, essentially.
Wow. Can you be more contemptuous of your users?
This antisocial behavior, which contradicts everything that social coding is supposed to stand for, is so rampant in OSS that it deserves an essay all its own, and no doubt it will get one. They don’t call me cantankerous for nothing.
Let’s take this apart
From the top:
This discussion is the perfect example why we will not be introducing additional options to the built in formatter.
In essence: devs have different preferences on matters of style (semicolons, single or double quotation marks, tabs or spaces), none of which has any effect on the quality of the code, ergo we should force everyone to use the same style.
Which style would that be? Why the one they chose for utterly arbitrary reasons.
And note: if the option is already in Dprint and you’re just blocking it, then that isn’t really “introducing additional options” is it? It’s taking them away.
Then he says:
All source code written for Deno should use the same formatting options for consistency, and to reduce this kind of discussion.
There is no evidence given to show that consistency across distinct and unrelated applications is necessary or even desirable. None. Are you going to regulate how many blank lines I can have? Whether I use two, three, or four space indentation? What and when I indent?
I am sure they would if they could. But let’s take this further. What really matters in code?
Naming.
That’s the number one most important thing in coding. Bad naming makes code unreadable and/or incomprehensible, and creates confusion and bugs.
So how are you going to enforce consistency in naming? Please tell me.
What about paradigms? Are you going to force everyone to code in an OO or functional style? Will you reject code if it doesn’t match that style? Can you believe that those dumb folks who created JavaScript gave users the option of doing OOP or FP? What were they thinking!
Am I allowed, your highness, to use a while
loop? The reduce
method? Global variables?
(I once had to give up on a new, promising linter because it kept flagging my use of the reduce
method. There was no way to turn this off. The arrogant pricks behind this linter had decided that they knew better than their users, and rather than giving their users a valuable tool that they could use to code to their preferred style, they decided to give them a straitjacket. Not this boy. I’m no fan of B&D.)
No, on all of these things—the things that really matter to good coding—no consistency is required at all. It’s only the utterly irrelevant but important-to-individual-coders things that evoke totalitarian responses.
And which formatting “options” will we be limited to? Why his, of course: our Great Dictator. Big Brother.
I’ve got news for you lucaconsonato, whoever you are. These decisions will not “reduce this kind of discussion”. They will just anger potential converts and drive them away. You can slam the door in the faces of the people you should be listening to, but you will not shut them up.
They’ll find another venue, or they’ll walk. They are not going to go back to using semicolons just because lucaconsonato insists on it.
Deno has already pushed me away. I will not be promoting it any longer. I can see that the totalitarian “we know better than you do” arrogance of the devs behind it will be effectively suicidal. No wonder uptake is so slow. Why tie myself to a sinking ship?
Ya know, Bun is looking pretty good.
He goes on:
In our eyes ecosystem consistency is much more important than opinions of individuals.
Unless they are the opinions of the committers, of course. The committers speak ex cathedra. Their opinions aren’t opinions but revealed truths. Duh!
And who are these individuals whose opinions (read: preferences) are unimportant? Oh, their users. What a brilliant way to win friends and influence people!
And what a great sales pitch! You can’t have it your way!
He finishes with:
This is also why we limit configuration options of the runtime and type checker as much as we do.
What blatant bullshit! Is he really saying that configuration of the runtime and type checker is equivalent to tabs vs. spaces or semicolons vs. no semicolons? Can he really be that ignorant?
No, of course not. The entire comment from lucaconsonato is utterly disingenuous. But he can’t be honest and say what he really means because that would make him look bad. So I’ll translate for you.
We like semicolons and we hate code that doesn’t use them so we’re going to shove them down your fucking throats. Now get lost!
And there you have it. And that is the entire argument. There’s nothing else.
And I’ve yet to see one person who prefers to leave the semis out say that everyone else must do the same.
Funny that.
The final nail in the coffin
But let’s finish by destroying the feeble arguments that the semicolon fascista make—and I am being very generous in calling them “arguments”.
First, they say that code is more readable and understandable with semicolons.
I guess that this code is unreadable then:
if (n < 1) { return n }
What? If statements take no semicolon? How confusing!
What about this?
function add(x, y) { return x + y }
What?? Function definitions don’t take a semicolon either? How bewildering!
In truth, it is difficult for beginners with JavaScript to figure out where to put a semicolon and where to leave it off.
I’ve taught a lot of beginners and they learn faster and less painfully without semicolons.
Surprisingly, extra semicolons generally don’t cause problems. Are they “dangerous”, too? Maybe it’s safer to leave them off and let ASI decide, no?
Hmm. Class definitions don’t take semicolons either? Loops? I’m seeing a pattern here.
The truth is that it is easier to write code without semicolons. Just that much less cognitive load.
This:
export default function pipe<T>(
fns: Array<(t: T) => T> = []
): (t: T) => T {
return (input) => fns.reduce((out, fn) => fn(out), input);
}
Is not in any way made less comprehensible when written like this:
export default function pipe<T>(
fns: Array<(t: T) => T> = []
): (t: T) => T {
return (input) => fns.reduce((out, fn) => fn(out), input)
}
So the comprehensibility argument is utterly specious.
But there’s still the big one: leaving out the semicolons is somehow dangerous. You can’t trust ASI to get it right!
Wow! What a terrific diss on the programmers who wrote the ASI code. I guess they just didn’t know what they’re doing. All these years to get it right and it’s still broken, no?
I mean, you wouldn’t want to rely on it, right? It’s not like we rely on any other code, like, say, the runtime. Or the app itself. Maybe we should just give up on this coding stuff.
And when they wrote ASI, they couldn’t have intended to make semicolons optional. They just put all that effort into ASI because, well, hmm… there had to be a reason.
But what is it that we’re really talking about here? The issue was about allowing coders to write code without semicolons and then format it with deno
fmt
without the formatter reinserting semicolons.
That’s what folks were asking for: Please do not shove semicolons down our throats.
No one is arguing that coders can’t write their code without semicolons. Obviously, we can.
What the Deno folks are saying is that the Deno formatter put them back in every time you run deno
fmt
, as, for example, on save.
In short, the Deno formatter is going to insist on putting semicolons back in your code whether you want them or not. That’s what lucaconsonato demands.
And, pray tell, how will it do that?
How does Deno format know where to put the semicolons I left out or maybe forgot or put in the wrong place?
Can you guess?
Ha, ha. Wait for it… wait for it… waaaaaaait for it…
It uses a form of automatic semicolon insertion. That’s the only way it can do it, unless someone at Deno is inserting those semicolons by hand.
If you forget a semicolon (or leave one out on purpose), deno
fmt
automatically inserts it.
Automatic.
Semicolon.
Insertion.
If that’s not ASI, then what is it?
So we’re supposed to believe that ASI can’t be trusted ergo we must permit the Deno formatter to add those semicolons back in… using ASI.
Seriously, folks, you can’t make this shit up.
And what’s even more amazing is that lucaconsonato is not talking about code submitted to the Deno repository. That’s their code and they can make any rules they want.
No, he is talking about all code written with Deno. He’s talking about my code.
So even if I’m writing code that will only ever be used on my local machine, I must use semicolons if I want to use the Deno formatter. Because Deno and lucaconsonato say so.
We’re done here, folks
It’s all over. Move along now.
The semicolon fascista—who are continually claiming that it is those who don’t care for semicolons who are the totalitarians and troublemakers, despite no one insisting that semicolon fanboys leave them out—are as naked as the proverbial emperor in his new clothes.
These fascists want to pretend that the issue is pro and con. The two sides are equivalent, so choose one. But if you choose the “wrong” side (not theirs), then you are bikeshedding (but they aren’t).
It is not pro and con. It is about personal sovereignty. It is about the freedom of each developer to decide how they want to format their own code vs. the tyranny of the totalitarians who believe that they know what is right for everyone.
That’s why people get so angry about this. It’s not semicolons that are at issue, or tabs vs. spaces, or size of indent—and we all know that size does matter, right?
It’s about having the freedom to decide for oneself. Or being dictated to by those who claim to know better.
Quod erat demonstrandum
Semicolons are optional in JavaScript and TypeScript except in rare corner cases, in which instances just start the line with a semicolon:
; [1, 2, 3].forEach((n) => arr[n] = n * n)
I don’t write mutable code if I can avoid it, so I virtually never come across these situations unless I’m playing around in the REPL. Formatters often fix this for you.
And if you really break the code, then it won’t work. So you find the corner case and fix it. Frankly, those cases are probably anti-patterns anyway. All the better to learn to avoid them.
As I said above, a million lines of code with no semicolon issues.
People who want to shove semicolons down every developer’s throat want to do so because they are opinionated, arrogant authoritarians. It’s Orwellian.
Or they are those who blindly follow the arrogant authoritarians—and their numbers are legion. If the Pope said it, then it must be true, no?
It is not because they have a single reasonable argument to back them up.
And when such people get control of software, such as lucaconsonato at Deno, the power goes to their heads and they become petty dictators: You’ll do what you’re told and shut up about it. We know what’s good for you better than you do!
Issue closed!
I’ve got a million lines of code that says they’re wrong.
Sorry, Luca. I think I’ll go work with the adult devs instead. The ones who don’t bikeshed but just let devs decide for themselves about these “trivial things”.