9

Most often, in a general-purpose imperative language - semicolons as statement-delimiters are either required, or completely disallowed (e.g. C and Python).

However, some languages, like JavaScript, allow you to opt out of delimiting your statements with semicolons, in favor of other delimiters (such as a newline).

What are the design decisions behind this? I understand that semicolons are essential when writing multiple statements on the same line, but is there another reason to make them mandatory (except following C)?

  • 1
    You need to think about statement terminators (perl, c), and statement delimiters (javascript, pascal). – user40980 Oct 2 '13 at 20:55
  • 5
    In Python, semicolons can be used to separate multiple statements on the same line. And since an "empty" statement is allowed, semicolons can be used at the end of most statements. – Greg Hewgill Oct 2 '13 at 21:22
  • 1
    I understand that semicolons are essential when writing multiple statements on the same line - Depends on the language. My favored one has no such delimiters at all, the next statement begins when all function arguments have been used up. – Izkata Oct 3 '13 at 1:02
  • 1
    @MichaelT: I don't think your classifications are correct: Perl arguably belongs to both groups, and JavaScript is actually in the "statement terminators" camp (since implementations are required to infer a semicolon before } or at end-of-file). – ruakh Oct 3 '13 at 3:40
  • Yes, absolutely depends on the language. My personal guess would be that semicolons are just a kind of commonly agreed convention, which most language designers follow. At least it makes some sense from a more natural-like language standpoint. Same with { and } for blocks, by the way: they are used by many languages, however not all and you actually don't have to do this. There is no universal reason behind this. – JensG Oct 3 '13 at 11:24
24

Making them mandatory (or disallowing them completely) reduces the number of corner cases, eliminates a potential source of obscure bugs, and simplifies the compiler/interpreter design.

The language designers who have opted to make them optional have chosen to live with the ambiguity in return for greater syntactic flexibility.

  • 7
    @RobertHarvey Heretic! There should be one, obvious way of doing it and only one. Incidentally, there's only one way to do it in perl. – user40980 Oct 2 '13 at 21:23
  • 1
    BTW - some languages have a fair amount of redundancy in the grammars in general, so making the semicolon optional is only occasionally ambiguous in practice. That said, I think the semicolon is the wrong bit of redundancy to drop - I quite like Haskell where you drop the parens and commas for arguments instead. OK, you can drop the semicolon too in Haskell, but it's not really the same thing as Javascript. – Steve314 Oct 2 '13 at 21:59
  • 2
    IIRC the problem is that they don't fit the formal model but that the parser generators don't produce good error messages. I.e. they have limited knowledge of common mistakes while hand-written parser can get much more useful error message. Gcc for example used to use bison for C grammar. Similarly the problem is that the 'edge cases' are not formal edge cases but soft ones - i.e. for parser the AST is clear and for human the AST 'is clear' but they don't agree what AST is like. – Maciej Piechotka Oct 2 '13 at 23:05
  • 2
    @Maciej Piechotka - I didn't mean to imply the parens were optional in Haskell. I'm talking about dropping something redundant as a language design decision. The point is that you don't use parens or commas for a function call in Haskell. You can pass a tuple as an argument, but that's still the syntax for a tuple, not for passing arguments. Haskell (and ML and others) "dropped" the parens and commas for function arguments in the sense that there's this common convention in other languages (since Algol?), but Haskell doesn't do that. – Steve314 Oct 3 '13 at 0:36
  • 1
    @Maciej Piechotka - Of course it was never really a universal convention anyway - just because Algol-family languages do it doesn't mean other languages define themselves relative to that, so my "dropped" claim is wrong in that sense - but with all the C-family languages these days it feels a bit like that. – Steve314 Oct 3 '13 at 0:38
15

JavaScript has shown us that this is a very bad idea. For example:

return
0;

In C, this returns a value of 0. In JavaScript, this returns undefined because a semicolon gets inserted after the return statement, and it's not immediately obvious why your code is breaking unless you happen to know about the details of automatic semicolon insertion.

  • 1
    @delnan: Python isn't designed to look like C. It's well-known to be indentation-based and thus highly line-oriented, and It doesn't require semicolons. JavaScript technically does require them; it's inserting one when it finds one missing, which transforms what looks like one syntactically valid statement into two distinct statements with completely different semantics. – Mason Wheeler Oct 2 '13 at 23:41
  • 7
    It's not a bad idea, it's just confusing to people who try to use JavaScript without bothering to learn about its automatic semicolon insertion. Perhaps instead of saying "this is a very bad idea" you could more accurately say "making semicolons optional introduces pitfalls for programmers who don't go out and learn all the details". – TehShrike Oct 3 '13 at 0:38
  • 4
    @delnan: The reason it's surprising is that JavaScript usually doesn't insert a semicolon at the end of a line, except to fix an otherwise-invalid program. After return is one of only a handful of cases where JavaScript will insert a semicolon even if the program would be valid without it. (But of course, this undermines Mason Wheeler's point. The problem isn't that the semicolons are optional, it's that the rules are inconsistent.) – ruakh Oct 3 '13 at 3:34
  • 6
    @TehShrike: Making semicolons optional introduces pitfalls for all programmers, because it arbitrarily interprets typos instead of asking you what you meant. Everybody makes a typo now and then. – Jan Hudec Oct 3 '13 at 7:10
  • 1
    javascript has shown that its implementation of optional semicolons is flawed. It doesn't show that optional semicolons are bad per-se. – CodesInChaos Oct 8 '13 at 10:58
4

It simplifies your grammar and parser somewhat to make the semicolons mandatory. Essentially, it allows the lexer to dump all the whitespace, including newlines, and the parser doesn't have to worry about it at all.

On the other hand, once you start wanting to tell the parser about whitespace anyway, it's not that hard to make the semicolons optional. You can often just lump them together with a whitespace token and your parser can handle it just fine.

For example, try inserting the semicolons into the following series of C statements.

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

While there are some weird things you can no longer do, like while(1);, for the most part, it's relatively easy with modern parsing techniques to determine where the statements end without a specific delimiter. Even if you still want to allow the weird stuff, it's not that hard to make a newline_or_semicolon non-terminal.

  • When C was originally developed in the early 1970s, statement terminators were needed to simplify compilers. By the mid-90s, when Javascript was developed, it was less of a concern. – Sean McSomething Oct 8 '13 at 16:33
3

Semicolons are useful in a grammar for 2 reasons. First, it lets you split long statements into multiple lines without having godawful continuation characters (I'm talking about you, Fortran and Basic). Second, it let's the parser have a way to "give up" parsing when the syntax gets really convoluted because of a typo. Stealing from Karl Bielefeldt's example,

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

imagine you typed one extra open paren:

functionCall((3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

now where is the mistake? If you had the semicolons, it is easier for the parser to give up at the first semicolon. It could even continue parsing after the semicolon if it wanted to.

functionCall((3, 4);  <- something is wrong here. emit error and keep going.
                      9 + (3 / 8); variable++; while(1) { printf("Hello, world\n"); }

Now it is easier on the parser to report an error, and easier to locate the line/column where it occurred.

  • 1
    Fortran and Basic at least have decently chosen line-continuation markers (& and _, respectively). For sheer ""OMG, what were they thinking", nothing beats FoxPro. To continue a line, you used a semicolon. – DougM Oct 8 '13 at 3:51
1

Semicolons are not always all-or-nothing like you mention in your question. For example, Lua's grammar is carefully designed to be free form (all whitespace, including newlines, can be ignored) but also without needing to use any semicolons. For example, the following programs are equivalent:

--One statement per line
x = 1
y = 2

--Multiple statements per line
x = 1 y = 2

--You can add semicolons if you want but its just for clarity:
x = 1; y = 2
0

All design and construction aside, I believe that a lot of programmers come from different backgrounds and some learned to use the semi-colon and some didn't. A lot of newer languages that are emerging aren't requiring a semi-colon but still allow it to exist. I think it might just be a way of getting more programmers to learn how to code in these new languages without having to give up their habits from when they began.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.