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. |
|||||||||||||||||||||
|
|||||||||||||||||||||
We're looking for long answers that provide some explanation and context. Don't just give a one-line answer: please explain why you're recommending it as a solution. Answers that don't explain anything will be deleted. See Good Subjective, Bad Subjective for more information. |
|||||||||||||||||||||
|
In English the semicolon is used to separate items in a list of statements, for example
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 Edit again
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 Since in C the statement terminator is 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. |
|||||||||||||||||||||
|
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. |
|||||||||
|
|
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 The main reason
What other symbol could you pick? The ASCII characters #$@[]^_`{|}~ weren't always present in early character encodings like ISO 646. The characters
Similar problems would apply to That leaves Choosing
The
can be read as a command to do thing A and then do thing B. But most languages with an The So that leaves
But |
|||
|
|
|
Rather than trying to answer your headline question, I think it's better to focus on your implicit question:
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.)
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!” |
||||
|
|
|
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.] |
||||
|
|
|
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. |
|||||||||||||||||||
|
|
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. |
|||
|
|
|
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 There was probably no other character which could be used as statement separator as intuitively ( |
|||
|
|
|
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. |
||||
|
|