Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In many languages (a wide list, from C to JavaScript):

  • commas , separate arguments (e.g. func(a, b, c)), while
  • semicolons ; separate sequential instructions (e.g. instruction1; instruction2; instruction3).

So why is this mapping reversed in the same languages for for loops:

for ( init1, init2; condition; inc1, inc2 )
{
    instruction1;
    instruction2;
}

instead of (what seems more natural to me)

for ( init1; init2, condition, inc1; inc2 )
{
    instruction1;
    instruction2;
}

?

Sure, for is (usually) not a function, but arguments (i.e. init, condition, increment) behave more like arguments of a function than a sequence of instructions.

Is it due to historical reasons / a convention, or is there a good rationale for the interchange of , and ; in loops?

share|improve this question
1  
(My f1rst post here. I am not sure whether this question belongs more to Programmers or SO, so feel free to migrate, if it is needed.) –  Piotr Migdal Apr 21 '13 at 21:23
8  
This is definitely a Programmers post. Welcome! :-) –  Martijn Pieters Apr 21 '13 at 21:49
    
@MartijnPieters Great! And thanks. :) –  Piotr Migdal Apr 21 '13 at 21:53
1  
"Why Not" will provide the answer - by having the same answer - "Because someone needed to make a choice, and that is the choice they made" Same as "Why did they choose "{" and "}" and 1000 other choices they made - "Because". –  mattnz Apr 21 '13 at 22:41
2  
@mattnz The question is about consistency (not "Why we use ; not |?" (or Why do we use 'else' not 'otherwise'?)) which is not case for one language, but a big number of them. An answer that e.g. "it was made in C as a shorthand for while loop (and multiple statements for inc were thought only later), and people didn't want to change it to avoid programmers' irritation" would be perfectly fine. –  Piotr Migdal Apr 21 '13 at 22:48
show 2 more comments

7 Answers

up vote 18 down vote accepted

So why in the same languages such mapping is reversed for for loops.

Technically, the mapping is not "reversed".

  • The things separated by commas are not parameters. In (at least) C++ and Java, they can be declarations, so they are not even expressions.
  • The things separated by semicolons are not (single) statements either.

In reality what we have here is a different syntactic context where the same symbols are being used differently. We are not comparing like with like, so there is no mapping, and no strong argument for a consistent mapping based on semantic consistency.

So why not do it the other way around?

Well I think the reasons come from the "natural" meaning of , and ;. In English written language, a semicolon is "stronger" break than a comma, and the glyph for semicolon is more visible than a comma. Those two things combine to make current arrangement seem (to me!) to be more natural.

But the only way to know for sure why the syntax choice was made would be if the C designers could tell us what they were thinking back in ~1970. I doubt that they have a clear memory of technical decisions made that far back in time.


Is it due to historical reasons / a convention

I'm not aware of any language before C that used a C-like syntax for "for" loops:

  • Donal Fellows notes that BCPL and B didn't have an equivalent construct.

  • The FORTRAN, COBOL and Algol-60 (and Pascal) equivalents were less expressive, and had syntaxes that did not resemble C "for" syntax.

But languages like C, C++ and Java that came after C all clearly borrow their "for" syntax from C.

share|improve this answer
    
So, the philosophy of (, vs ;) is (weaker vs stronger break), rather than (tuple- vs sequence-splitter), right? Still for me it is not obvious whether arguments or statements need stronger breaks (as in many cases for a sequence of statements, breaks are implicit (see e.g. JavaScript (e.g. i++[line break]j++))), but at least now I get the point why the current convention is not "obviously reversed". –  Piotr Migdal Apr 21 '13 at 23:39
    
@PiotrMigdal the comma as a delimiter would prevent the use of the comma operand and might imply the components of the for loop are statements rather than expressions. This has significant implications. –  MichaelT Apr 22 '13 at 0:04
    
The last comment made me curious what BCPL did, but apparently there it was FOR i = e1 TO e2 BY e3 DO c (e1..e3 expressions, c command), which more closely resembles BASIC's syntax. Source –  Michael Kjörling Apr 22 '13 at 7:41
1  
@PiotrMigdal - The "philosophy" is whatever K&R and the rest were thinking back in 1970. I don't think it went to the depth of thinking that you imagine. (They were trying to implement a "higher level" language to avoid having to write masses of telephone switch software in assembler.) –  Stephen C Apr 22 '13 at 7:46
    
I just checked; the for syntax was introduced in C (it wasn't in B or BCPL). –  Donal Fellows Apr 22 '13 at 10:16
show 5 more comments

We write loops like:

 for(x = 0; x < 10; x++)

The language could have been defined so that loops looked like:

 for(x = 0, x < 10, x++)

However, think of the same loop implemented using a while loop:

 x = 0;
 while(x < 10)
 {
     x++;
 }

Notice that the x=0 and x++ are statements, ended by semicolons. They aren't expressions like you would have in a function call. Semicolons are used to separate statements, and since two of the three elements in a for loop are statements, that's what is used there. A for loop is just a shortcut for such a while loop.

Additionally, the arguments don't really act like arguments to a function. The second and third are repeatedly evaluated. It's true they aren't a sequence, but they also aren't function arguments.

Also, the fact that you can use commas to have multiple statements in the for loop is actually something you can do outside the for loop.

x = 0, y= 3;

is a perfectly valid statement even outside of a for loop. I don't know of any practical use outside the for loop though. But the point is that commas always subdivide statements; it's not a special feature of the for loop.

share|improve this answer
    
Sure, I understand that "while" loop is "more fundamental". But such "short-hand notation" does not make much sense (at least to me), as you could start with x = 0; y = 0; and (inside the curly bracket) x++; y++;... –  Piotr Migdal Apr 21 '13 at 21:42
2  
@PiotrMigdal, oh you could. My point is that the pieces inside the for loop are statements (which are separated by semicolons) not expressions (which are separated by commas) –  Winston Ewert Apr 21 '13 at 21:44
1  
I get the difference, just for me ; is natural for a sequence of statements, not necessarily separating any statements (so is it just that tastes differ?). And in the current convention one occasionally ends up with separating sequences of statements with commas anyway... –  Piotr Migdal Apr 21 '13 at 22:14
3  
@PiotrMigdal, members of structs/unions are seperated by semicolons, but those aren't really sequential. So its certainly not restricted to a sequence of statement in its use. At the end of the day, syntax does rather come down to taste. –  Winston Ewert Apr 21 '13 at 22:18
    
I don't know of any practical use outside the for loop though --- How about (foo)?bar++, qux++:bletch --- Where you want the ?: expression to do two things rather than just one. The return value if foo is true is qux, but both bar and qux get incremented. –  MichaelT Apr 21 '13 at 23:14
show 4 more comments

Maybe this is something specific for C/C++, but I post this answer, because the syntax of the lagnuages you described is mostly influenced by the C-Syntax.

Besides the previously answered questions are true, from a technical point of view, that's also because in C (and C++) the comma is actually an operator, that you can even overload. Using a semicolon-operator (operator;()) would possibly make it harder to write compilers, since the semicolon is the axiomatic expression terminator.

What makes this intersting is the fact, that the comma is widely used as seperator all over the language. It seems like the comma operator is an exception, that is mainly used to get for-loops with multiple conditions working, so what's the deal?

In fact the operator, is built to do the same thing like in definitions, argument lists, and so on: It has been build to seperate expressions - something the syntactic construct , cannot do. It can only seperate what has been defined in the standard.

However the semicolon does not seperate - it terminates. And this is also what leads us back to the original question:

for (int a = 0, float b = 0.0f; a < 100 && b < 100.0f; a++, b += 1.0f)
    printf("%d: %f", a, b);

The comma seperates the expressions in the three loop parts, whereas the semicolon terminates a part (initialization, condition or afterthought) of the loop definition.

Newer programming languages (like C#) may not allow overloading the comma-operator, but they most likely kept the syntax, because changing it feels somehow unnatural.

share|improve this answer
    
There's a problem with this argument. In a for statement the ; symbol is plainly used as a separator. It separate the 3 syntactic parts of the statement. There is not 3rd semicolon to "terminate" the progressive expression list. It is terminated by a different token - ). –  Stephen C Apr 26 '13 at 0:08
add comment

The easiest way to see it is the following:

for(x = 0; x < 10; x++)

is:

for(
x = 0;
x < 10;
x++
)

In other words, those x = 0 thingy is actually a statement/instructions rather than a parameter. You insert a statement there. Hence they are separated by semicolon.

In fact there is no way they are separated by comma. When do the last time you insert things like x<10 as a parameter? You do that if you want to computer x<10 once and insert the result of that operation as parameter. So in comma world you would put x<10 if you want to pass on the value of x < 0 to a function.

Here you specify that the program should check x<10 every time the loop is passed. So that's an instruction.

x++ is definitely another instructions.

Those are all instructions. So they are separated by semi colon.

share|improve this answer
    
It isn't a statement. It is an expression separated by a semicolon. A statement is completely different. –  MichaelT Apr 22 '13 at 4:49
    
x < 10 may be an expression (which would usually be separated by semicolon. x=0 is definitely a statement/instructions. –  Jim Thio Apr 22 '13 at 4:52
    
Look at the bnf for C - if the for loop was statements, one could use other statements such as another for switch or return inside the for loop definition (ie for(int i = 0; if(i > 1024) { return; } ; switch (i % 3) { case 0; case 1: i++; case 2: i++; } ) { ... }) --- you can't. It isn't a statement. Instead it is defined as for ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement> –  MichaelT Apr 22 '13 at 4:57
    
Strange. int i =0 is an expression all right, but we do it mainly to declare an int namely i and assign 0 to it (it also returns 0 but as a side effect. You can't do for({int i=0;j=i};j<0;cout << "Hello world") can you? Or yea I think you can. –  Jim Thio Apr 22 '13 at 5:18
1  
@JimThio: You're probably not aware of it, but "statement" and "expression" have very precise meanings in language standards. int i = 0 definitely is NOT an expression. The set of rules describing an expression is fairly complex, considering what can constitute an expression, but the construct TYPE NAME = EXPRESSION matches none of those rules. –  MSalters Apr 22 '13 at 8:56
show 1 more comment

There is no conceptual reversal.

Semicolons in C represent more major divisions than commas. They separate statements and declarations.

The major divisions in the for loop is that there are three expressions (or a declaration and two expressions) and a body.

The commas you see in C for loops are not part of the syntax of the for loop specifically. They are just manifestations of the comma operator.

Commas are major separators between arguments in function calls and between parameters in function declarations, but semicolons are not used. The for loop is special syntax; it has nothing to do with functions or function calls.

share|improve this answer
add comment

In C and C++ this is the comma operator, not just a comma.

The grammar for a for loop is something like

for ([pre-expression]; [terminate-condition]; [increment-expression]) body-expression

In the case of your question:

pre-expression -> init1, init2
terminate-condition -> condition
increment-expression -> inc1, inc2

Note that the comma-operator allows you to perform multiple actions in one statement (as the compiler sees it). If your suggestion was implemented there would be an ambiguity in the grammar as to when the programmer intended to write a comma-operator statement or a separator.

In short, ; signifies the end of a statement. A for loop is a keyword followed by a list of optional statements surrounded by (). The comma-operator statement allows the use of , in a single statement.

share|improve this answer
3  
A for loop is a set of expressions separated by semicolons. Statements can be much more than expressions - one can't slip a case statement or if statement into a for loop parts. It is a significant implication to say that the components of the for loop are statements when one looks at the bnf form of a for loop –  MichaelT Apr 22 '13 at 0:02
    
@MichaelT: But in C++ the syntax of a for loop explicitly allows a statement (declaration) as its first part. (C++ allowed declarations mid-function, as opposed to its predecessor C89). You can't generalize such statements across languages, even for 2 languages as close as C and C++. –  MSalters Apr 22 '13 at 8:50
    
@MichaelT Did you miss the 'is something like' part? –  James Apr 22 '13 at 9:21
    
@James you can avoid the "something like" by using the actual bnf of for ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement> for C and for ( for-init-statement; conditionopt ; expressionopt ) statement for C++ --- The ';' does not only signify a statement terminator. A for loop is not followed by statements enclosed in (). –  MichaelT Apr 22 '13 at 13:53
1  
+1 for mentioning the comma-operator –  Axel Apr 23 '13 at 7:38
add comment

For me they are used more less similar meaning to their linguistic sense. Commas are used with lists and semicolons with more separate parts.

In func(a, b, c) we have a list of arguments.

instruction1; instruction2; instruction3 is maybe a list but a list of separate and independent instructions.

While in for ( init1, init2; condition; inc1, inc2 ) we have three separate parts - a list of initializations, a condition and a list of increment expressions.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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