Is there a reason that a semi-colon was chosen as a line terminator instead of a different symbol?
I want to know the history behind this decision, and hope the answers will lead to insights that may influence future decisions.
Is there a reason that a semi-colon was chosen as a line terminator instead of a different symbol?
I want to know the history behind this decision, and hope the answers will lead to insights that may influence future decisions.
In English the semicolon is used to separate items in a list of statements, for example
She saw three men: Jamie, who came from New Zealand; John, the milkman's son; and George, a gaunt kind of man.
When programming you are separating a number of statements and using a full stop could be easily confused for a decimal point. Using the semicolon provides an easy to parse method of separating the individual program statements while remaining close to normal English punctuation.
Edit to add
In the early days when memory was expensive, processing slow, and the first programming languages were being devised, there was a need to split the program up into separate statements for processing. Some languages required that each statement was placed on a line so that the carriage return could act as the statement delimiter. Other languages allowed a more free format to the text layout and so required a specific delimiter character. This character was chosen to be the semicolon, most likely because of the similarity to its use in the English language (this has to be a supposition; I was not there at the time) and as it did not produce a conflict with the other punctuation marks and symbols that were required for mathematical or other syntactic purposes.
Edit again
The need for some terminator character goes back to the requirements for parsing the language text. The early compilers were written in assembly language or, in some cases, directly in hand crafted binary machine instructions. Having a special character that identified the end of the statement and delimited the chunk of text that is being processed makes the processing that much easier. As I said above, other languages have used the carriage return or brackets. The Algol, Pascal, Ada, BCPL, B, C, PL/M, and other families of languages happen to use the semicolon. As to which one was first to use this particular character, I do not go back far enough in history to remember. Its choice and adoption makes perfect sense as
As a final remark, I think that there has been more time spent on these answers and comments than was spent in deciding to use the semicolon to end a statement when designing the first language that used it in this way.
Many languages use syntax that is modeled after C (which was modeled after B - thanks @Crollster). As can be seen in the comments, there is a long chain of such languages... B was inspired by PL/I, which was preceded by ALGOL at using the ;
as a separator.
Since in C the statement terminator is ;
, these languages follow suit.
As for why it was selected as a statement terminator in C - possibly because of its use in English "to indicate interdependent statements".
C was also invented on the PDP-11 at a time where there was limited amount of memory available for character sets, so the inventors of the languages had to work within these constraints.
FORTRAN used carriage return to delineate statements. COBOL used period. LISP didn't use anything, relying on parentheses for everything. ALGOL was the first language to use semicolon to separate statements. PASCAL followed ALGOL's lead, using semicolon to separate statements.
PL/I used semicolon to terminate statements. There is a difference, and it is easily seen in PASCAL. Ada followed PL/I's lead on this one item, rather than ALGOL's.
Semicolon as statement separator or terminator was quickly accepted by the computer science community as a useful notation, and, as far as I know, every subsequent block-structured language followed ALGOL's lead and used semicolon to separate or terminate statements.
I was told many years ago that BCPL used both semicolon AND carriage return as statement separators/terminators, but I never used the language myself and am unable to verify this. At some point, the use of carriage return to separate or terminate statements was dropped from the BCPL descendants. BCPL begat B, B begat C, C begat C++, Java, D and a whole host of things considerably less well-thought-out than PASCAL and Ada.
Why not any other symbol?
A few languages have used other symbols -- old versions of BASIC used a colon instead, for one example.
Ignoring the few exceptions, however, I think there are two primary reasons. The first is that you're simply looking for something unambiguous. In a typical parser, if you run into a serious enough error that you can't continue parsing the current statement, you normally try to get the parser back in sync by just skipping ahead to the statement terminator and re-start the parser from the beginning of the next statement. For that, you want something that won't normally occur anywhere else in the code, and a semicolon happens to be a symbol with little other meaning attached, so it's pretty easy to dedicate it to this purpose.
The second reason is somewhat similar, but aimed more toward people reading/using the code. Again, it comes back to the fact that the actual symbol you use doesn't matter much. There's a substantial advantage in readability to gain from using the symbol your reader is accustomed to seeing for a particular purpose, when and if possible. That doesn't mean that C is the one perfect syntax and everything else should follow it slavishly, but it does mean that enough people are familiar with that style of syntax that a vaguely similar language gains a lot (and loses very little) by following roughly the same syntax where it can.
I'd note that this is much like designing almost any other program. If I write a program that uses windows of some sort, I'll try to just use the native features of the target platform(s). Many of the decisions that embodies will be largely arbitrary, and could be done differently without any major loss of functionality -- but equally, changing them without a substantial gain in functionality just confuses users without accomplishing anything useful. The same basic principles apply to "what should terminate (or separate) statements in a language?" as "what should a scroll bar look like", or "how should a tree control work?" In all these cases, the decision is mostly arbitrary, and uniformity provides a substantial benefit in and of itself.
I'd add that much the same happens throughout many languages, just in ways that most of us are so accustomed to before programming that few people think about it. Why does everybody use "+" to indicate addition, or "-" to indicate subtraction? Because the shape of the symbol doesn't matter much, but everybody agreeing to apply the same meaning to each symbol matters a lot.
Semicolon was originally proposed in Algol 60 as a statement separator, not a terminator.
Prior to Algol 60, the only high-level programming language in existence was Fortran, which required each statement to be on a separate line. Statements spanning multiple lines, like do-loops, were considered an oddity, and they were regarded as 'statement blocks'.
The designers of Algol 60 realized that statements needed a hierarchical structure (if-then-else, do-loops, case statements etc) and they could be nested inside each other. So, the idea of each statement sitting on a separate line didn't make sense any more. Sequential composition of statements of the form S1; S2; ...; Sn optionally enclosed in begin - end brackets were called compound statements, and fit into the hierarchical structure of statements envisaged by Algol 60. So, here, the semicolon is clearly a statement separator, not a terminator.
This gave rise to problems in practice. Algol 60 also had an "empty statement" which was denoted by writing nothing. So, one could write "begin S1; end" where the semicolon appears as if it is terminating S1. But the Algol 60 compiler really treated it as a separator between S1 and an invisible empty statement following it. These subtleties were a bit much for practical programmers. Having been used to line-oriented languages like Assembly and Fortran, they really thought of semicolon as a terminator for statements. When programs were written out, usually semicolon was put the at the end of the statements, like so:
a[i] := 0; i := i+1
and the semicolon really looked like a terminator for the first statement. If the programmers treated the semicolon as a terminator, then statement like this would give a syntax error:
if i > 0 then a[i] := 0; else a[i] := 1;
because the semicolon terminates the "if" and, so, the "else" becomes dangling. Programmers were thoroughly confused.
So, PL/I, which was the IBM's successor to line-oriented Fortran, decided to make the semicolon a statement terminator rather than a separator. Programmers were happy with that choice. The majority of programming languages followed suit. (Pascal resisted the trend, but its successor Ada gave up on it.)
[Note added: Wikipedia article on programming language comparisons has a nice table summarizing how semicolon is treated in various programming languages.]
This is pretty much pure guess work, but looking at a standard QWERTY keyboard restricted to ASCII values the natural characters for termination/separation would be .!?,:; and carriage returns. of those !?: should be immediately disqualified for taking multiple keys and statement termination is going to be a very common thing. Periods would be disqualified because they are easily confused with decimal points which would make them unnecessarily complicated to be a terminator given the limited space of initial computers. carriage returns would be disqualified after lines of code had potential to be longer than what can be shown on a single line on the screen, so it would be more difficult to read a program when lines had to be scrolled horizontally, or require additional characters to create a continuation on the next line which again adds complexity. this leaves , and ; as options, of those , is used much more often in writing compared to ; so the semicolon is chosen because its the easier to type, less confusing because its adding meaning to a character with limited meaning and less complicated because special cases don't really exist with its use.
The semicolon was chosen because it was the best character based on laziness and simplicity.
It's largely an arbitrary choice. Some languages have made other choices. COBOL terminates statements with the .
character. FORTRAN, BASIC, and Python generally terminate statements with newlines (with special syntax for multi-line statements). And Lisp brackets its statements with parentheses.
The main reason ;
is so popular as a statement separator/terminator is that most of today's popular languages are based on ALGOL, which used that convention.
instead of a different symbol?
What other symbol could you pick?
The ASCII characters #$@[]^_`{|}~ weren't always present in early character encodings like ISO 646.
The characters ()*+-/<=>
are typically used as mathematical operators and would create parsing ambiguities if used as statement terminators.
product = a * b * // If '*' were a statement terminator,
c * d * // Are there two factors, or four?
Similar problems would apply to '
and "
, which are typically used as string delimiters; ,
, which is typically used to separate function arguments, and .
, which is typically used as a decimal point (or as a delimiter in constructs like some_struct.some_field
).
That leaves !%&:;?
.
Choosing !
or ?
probably wouldn't cause technical difficulties, but their English meanings would give the wrong mood to the program.
print(x)? # Yes, you should.
# It's an IMPERATIVE language; stop questioning my commands.
print(x)! # OK! You don't have to shout!
The &
would be a more sensible choice as a statement separator (not terminator), because
do_thing_a() &
do_thing_b()
can be read as a command to do thing A and then do thing B. But most languages with an &
operator use it as a logical or bitwise AND instead.
The %
sign might cause confusion in statements like interest_rate = 2.99%
(which would set the variable to 2.99
instead of the expected 0.0299
). Of course, the well-known mathematical meaning of %
didn't stop C from using it as the remainder operator.
So that leaves :
and ;
.
:
is a sensible choice, and indeed is used as the intra-line statement separator in most dialects of BASIC.
But ;
has English grammar on its side; it can be used to separate clauses within a sentence.
Rather than trying to answer your headline question, I think it's better to focus on your implicit question:
I want to know the history behind this decision, and hope the answers will lead to insights that may influence future decisions in the design and implementation of programming languages.
If you want to learn about programming language design and implementation history, and gain more insight into the process, then the proceedings of the History of Programming Languages Conferences are a very good place to start. (I think you will need an ACM membership to be able to access the proceedings though.)
Why are statements in many programming languages terminated by semicolons? Is there a reason that a semi-colon was chosen as a line terminator instead of a different symbol?
Taking your headline question as an example question that you might want to try to answer by reading the HOPL proceedings, I'd like to offer the following point: people designing a new programming language usually do so because they consider the ones they know to be broken / deficient somehow. Their new language is, on one hand, designed to fix this deficiency. On the other hand, language designers will also copy design elements from other languages that they think are good, or they simply don't change those elements that they didn't experience a problem with.
Especially that last part is important: instead of trying to find out which programming language ever was the first one to use semicolons as terminators and why a lot of other programming languages copied that, you will probably learn more by looking at languages that did not copy it. For example, while Smalltalk took a lot of inspiration from Simula, it did not copy its syntax and in particular its use of semicolons as statement terminators. It changed terminators (separators really) to a full stop, and uses the semicolon for something else. Conversely, the first language that ever used a semicolon as a statement terminator may have had a reason to change this from what was used in languages that came before it. It's also possible that it was the first language to introduce the whole concept of a statement terminator (or did so independently of other languages) and that the semicolon was used for some reason that is now lost to time. (I suspect the latter is the case here, as none of the other answerers have been able to dig up a quote from the person who introduced the semicolon rather than offer retrofitted suppositions about why the semicolon was a good choice.) But to restate my point, I think you will learn more by looking at why language designers changed things rather than why they copied/kept them. When people change things they usually want or have to explain the change, while they don't do so when copying or keeping things the same because “why would we change it? that's just the way it's done!”
Its about visibility.
Early statement separators were the '.' as in COBOL and new line, carriage return in FORTRAN.
The CR proved limiting in that it makes it difficult to flow a statement over several lines.
Full stop caused a more interesting problem. When you read English text your brain processes the full stops at a subliminal level, you are conscious that a sentence has ended and you can pause for breath but you don't really notice the . that signaled it. Also in many fonts the '.' is the smallest possible character sometimes rendered as a single pixel. Missing or extra periods became the single most common cause of errors in COBOL programs.
So learning from early mistakes ALGOL pick a specific terminator which would allow a statement to flow over several lines, and, picked one that was visible and easily noticed by human readers. The semi-colon being both large and unusual enough in common English not to be processed subconsciously.
It was my understanding that it was chosen because there was a need for an explicit statement-terminator other than a carriage-return/new-line. Back in the days of 80-column screens, actually having a single line of code wrap across multiple lines was common enough that using \r or \n for the statement terminator would not work.
Semicolons were just convenient because they're not used in logic/math statements. As such, they don't conflict with the actual content of the statements to any significant extent.
Personally, I think the continuing use of the semicolon, together with style requirements to keep lines under 80 characters, is frankly stupid and anachronistic. Languages like python have extensively demonstrated that you can write easy to understand, concise code more easily without them. Also, if you have issues with lines that are longer then 80 chars, you need a bigger monitor.
Here are two questions: Why ALGOL got semicolon and why other languages went after it.
The first question is already answered in many ways here.
As the second one, The ALGOL was very widely used as a pseudocode language for algorithms writing. So, semicolons soon became natural for users of different languages. And naturally they were taken for the younger languages.
I might be wrong, but I think this has something to do with the fact that in many assemblers a semicolon was used to start a comment, usually put after an instruction. Everything after a ;
was a comment, and no longer a part of the instruction itself.
Then there is a need to terminate instructions when you're typing them in an interpreter. Short instructions (e.g. mathematical expressions) could be terminated by simply hitting the Enter key, telling the interpreter that the expression is ready to be calculated and it produced a result. But sometimes one wanted to input multiple lines of code for the instruction, so one way to achieve that was to use some special character as a terminator of the instruction instead of depending on just the Enter key. This way, the user could enter more lines of code at once, because Enter didn't send it to the interpreter yet. Only when the interpreter found the terminating character in a line entered with Enter, it would finally execute it and calculate its result.
Now combine these two things together, and the semicolon appears to be an obvious choice for the terminating character: it tells where the instruction part ends and the comment part starts, so when the interpreter encounters it in a line, it knows that it can flush all the lines of the expression it buffered so far and execute it, because the instruction has just ended, now we're in a comment (well, at least up to the end of this line, because the next line will start in the code mode again, starting a new expression/instruction).
This assumes, of course, that it was really the semicolon that has been used for comments by the person who come up with this idea of reusing it as instruction terminators. Having it been any other character, we might have ended up with a different instruction terminator.
Inb4: No, this is not a historical account. I don't have any evidence that this is the actual way semicolons came to life. It's just how I imagine it might have possibly happened.
Most languages took the semi-colon because it was already widely in use for that purpose and changing made no sense.
And considering the first languages to make that choice, you'll have to consider what are the alternatives. When designing a language, you want the needed characters to be available, and character sets at this time were coded on 6 bits, often with some patterns reserved, often with some characters not firmly defined (for a later occurrence of this, think about the national variants of ISO-646 -- the US variant is well know under the name ASCII -- which reuse the codes for "common" characters such as [
, #
or $
, and see the effect in a context where there is only half as many code positions available and letters and digits reserving more than half of those).
There was probably no other character which could be used as statement separator as intuitively (.
is probably already the only serious contender for that criteria) and without introducing lexing or parsing difficulties at a time when the parsing and lexing theory was still in elaboration (.
is now out of question due to its usage in real numbers).
Another reason why use semicolon is because it is one of the characters which we do not require or use more often.
Assume we use it more often as a variable name or some thing and if semicolon would have been used as a keyword or as a operator, it would have been a symbol conflict for the compiler, hence it was important to use a symbol which is not often used in the coding.
I believe C style programming languages made it popular and then authors of new programming languages do not wanted to reinvent the wheel and they continued using it, till now.