views:

1159

answers:

12

It sounds stupid, but over the years I haven't been able to come up with a use case that would require this. A quick google search didn't reveal anything worthwhile.

From memory there was a use case mentioned by Bjarne Stroustrup but i can't find a reference to it.

So why can't you have this in C languages:

int val = 0;
if val
  doSomehing();
else
  doSomehinglse();

EDIT I can accept the "we couldn't be bothered adding support to lexer" reason, I just want to figure out if this syntax breaks other language constructs. Considering how many whacky syntax features there are in C/C++, i hardly think this would have added much complexity.

Community Wiki now. So far the overwhelming consensus is that such syntx will wreck havoc with operators as pointed out here http://stackoverflow.com/questions/2061593/why-do-c-languages-require-parens-around-a-simple-condition-in-an-if-statement/2061613#2061613 and here http://stackoverflow.com/questions/2061593/why-do-c-languages-require-parens-around-a-simple-condition-in-an-if-statement/2061667#2061667.

Such syntax can also introduce ambiguity for while loops, although I am struggling to make it fit with the if statement: http://stackoverflow.com/questions/2061593/why-do-c-languages-require-parens-around-a-simple-condition-in-an-if-statement/2061663#2061663.

I think the best answer I've seen so far is in the comment by comment by hhafez. To paraphrase: In order to separate the condition from the statement one must either enforce parentheses around the condition or the braces around the statement. C chose the former in order to support missing braces.

+4  A: 

I think a better question would be "why would we want such a thing?" than "why don't we have it?". It introduces another otherwise unnecessary edge case into the lexer, just so you can avoid typing 4 extra characters; and adds complexity to the spec by allowing exceptions to a simple syntax that already supports all possible cases just fine. Not to mention toes the line of ambiguity, which in a programming language doesn't have much value.

Rex M
A lot of languages allow you to omit the parentheses and reducing noise always aids clarity. Pretending that it's some kind of insurmountable obstacle is a bit silly. The last part is more interesting. can you *think* of any cases where it'd introduce ambiguity? Otherwise your answer seems to be nothing more than "parentheses were always good enough for ME! Don't come here and suggest that my language isn't perfect"
jalf
Of course it adds complexity. The compiler has to figure out whether the programmer gave it a simple condition (i.e. a bool) or something more complicated; for example, what if the user has a statement 'if someObj doStuff()' where someObj has a huge function for implicit conversion to bool?
dauphic
I agree that C++ isn't the right language to be introducing such a feature. That said, I also think that we are underusing our natural "language instinct" in much of the code we write. Case in point: the previous sentence has only two quote marks and one comma for punctuation...but we both parse it the same in our heads. My suspicion is that there are many contexts where programming could leverage the latent shared understanding which allows us to do that. Lately I've been looking into exactly that question, it's been thought-provoking.
Hostile Fork
@dauphic: If you've ever written a parser, you'd know that it only introduces complexity if it creates any ambiguities where none existed previously. For this answer to be meaningful, it'd have to show such an ambiguity. If someObj can be implicitly converted to bool, then the compiler will do that, just as if there'd been ()'s around it. As long as that is the only way the code can be parsed, it'd add zero complexity.
jalf
@Hostile Fork. Unncessary boiler-plate is bad, but too much expressive flexibility can also be bad, even if it does not introduce ambiguity. You are writing code here, not poems. There is no need to make the compiler unreasonably complex (that could easily lead to bugs), and you have to think about the maintenance programmers as well. With a language of more flexibility (such as Perl), you can easily create write-only code, that becomes hard to figure out.
Thilo
@Thilo: If your coding isn't an art form on par with poetry, perhaps your sights are set too low. :) I'll compare with handwriting recognition: at the extremes are full OCR vs. entering your letters in binary ASCII. A compromise is something like Palm's Graffiti, which introduced exaggerated letterforms that people learned quickly and that computers could recognize without error. In my view programming languages tend to the extremes instead of asking both human and compiler to meet in the middle at a "sweet spot" of minimum complexity. Perl is not my ideal in this respect (can't stand it).
Hostile Fork
@jalf - "... reducing noise always aids clarity ..." is patently untrue. As a simple counter-example, why do you think some folks add parentheses that are strictly unnecessary? Because **for some people** the redundant parentheses aid clarity!!
Stephen C
@Jaff, do you want C to have Python's `pass` statement?
Hamish Grubijan
+40  A: 

If there are no brackets around expressions in if constructs, what would be the meaning of the following statement?

if x * x * b = NULL;

Is it

if (x*x)
    (*b) = NULL;

or is it

if (x)
    (*x) * b = NULL;

(of course these are silly examples and don't even work for obvious reasons but you get the point)

TLDR: Brackets are required in C to remove even the possibility of any syntactic ambiguity.

DrJokepu
ooh yeah, that seems likely. +1
jalf
… or `if ( x * x * b = NULL ) ;` will look fine to the parser until it tries to match functions to the operations.
Potatoswatter
This really isn't a good answer to the question. C strictly dictates the order of operations for operators. If that were valid syntax it would be evaluated as if(NULL) because * takes precedence over = and the return value of an assignment is the value assigned, and there is no logical reason why a compiler which didn't require brackets around a conditional would split the statement after the if (look at python syntax).
Chris
Chris: The point is, the LR parser needs to be able to decide where the condition ends and where the conditional block begins. Different languages have different approaches, some require brackets, some newlines and some have the "then" keyword. You just can't get around that. Show me _one_ language that doesn't have some mechanism for separating the conditional expression from the conditional block some way or other. If you still don't believe me, try to build your own language syntax with yacc and you will see all the issues that will come up.
DrJokepu
@Chris: even if there is an unambigious way to parse this, it would be much less obvious, and difficult to read, hence a bad idea. For example, I always put in extra parens with nested and/or/not conditions, even if they are not necessary. Saves everyone time thinking about how the implicit priorities would work out.
Thilo
This kinds sounds to me like allowing this will need to make `if` statement almost like an operator with its own precedence rules.
Igor Zevaka
@Chris: so you just arbitrarily decided to use a greedy algorithm and use the longest possible expression. That will end badly (pun intended). Python delimits the condition by the newline. Languages that don't require parens, like ML, don't alias symbols between unary and binary operators.
Potatoswatter
If someone adds a generalisation to this post, something like "In order to disambiguate condition from statement" for fatheads like myself I will accept it as an answer ;)
Igor Zevaka
Thanks for hte bold. I**definitely** get it now ;)
Igor Zevaka
can't you solve this by disallowing eliding braces? e.g. `if( foo ) bar;` becomes `if foo { bar; }`.
Logan Capaldo
Logan Capaldo: Yes, that would work too.
DrJokepu
C has an ambiguous grammar, parentheses in conditionals or not. Consider: `a * b;` What does it mean? A simple multiplication that throws away the result, or a declaration of a pointer? The grammar is ambiguous and the compiler needs context to resolve it. I think the answer to this question is "because that's the way it is, that's how Dennis Ritchie liked it".
wilhelmtell
By the way, the TLDR statement will not compile, it's meant to be TLDR;
Igor Zevaka
That same argumenmt can be applyed to a+b*c or any other chain operation. a+b*c is that (a+b)*c or a+(b*c) I know what the precedence rules says but they work equally on the given example. I'm sry but your answer is incorrect
Rune FS
@Rune FS: This is isn't about operator precedence, it's about semantics. Read all the comments here for more details.
DrJokepu
@DrJokepu I agree this post is about semantics and that's exactly my point. I don't believe the reason for the if() is semantics. C/C++ is extremely vague when it comes to semantics. Take a statement like this A=B=C it's absolutely impossible to state beyond any doubt what the result is. There's nothing that guarantees that A == C is true, you can't even count on A or B actually being assign. So it would seem very weird at one place to use semantics as the arguement and basically ignore it in the rest of the language.
Rune FS
A: 

I can't think of any specific cases where omitting the parens would actually cause any ambiguity, but there is probably a corner case somewhere.

It might be related to locally declared variables (as in if (bool b = foo())... where without the parentheses, it'd be harder to determine if bool is a type declaration or the the entire condition. In the latter case, b would then be the first token of the if-statements body, rather than part of the condition.

jalf
Except that allowing a variable definition as part of an expression was not part of the original C language.
R Samuel Klatchko
@R Samuel: True the example given doesn't apply to C
hhafez
A: 
OscarRyz
Great, this just reaffirms the notion that it's either braces or the parentheses.
Igor Zevaka
....Or as in Python ( I know it is not from the "C" family but ) using the colon to separate the sentence. It could be: `if x * x : b = None`
OscarRyz
A: 

I can give at least one example why in C there are paranthesis around conditions,

For example consider the following

while(1) do_something();

The above will call do_something() for ever in an infinite loop

The reason the parenthis are required is because the following would be ambiguous

while 1 ; do_something(); does that mean, evaluate do_something and do nothing in the while loop? or does it mean the same as the code sample above?

I guess that showes one way why in the C syntax parenthis are required around condition evaluations, and by extending the same syntax (for the sake of consitency) it is extended to the if statements.

Discalaimer: I could be completely wrong and the reason behind having the pranthesis could be completely different, but at least I've shown one example of how it can be useful

hhafez
What about "while 1 do_something();"? Removing the parenthesis removes the ability to express an infinite loop by omitting the condition, but it doesn't remove the ability to express an infinite loop.
ICR
Actually I think that needs to be while(1) do_something(). For me using gcc 4.0.1 I get _syntax error before ‘)’ token_ for your code.
Michael Anderson
thats true, but your syntactic rules should not allow ambiguos situations like I showed above, so either enforce () around condition statements or enforce {} around while/for/if/else body. C chose to do the first, or go the python route (ie: white space is important). From the outset C doesn't care about whitespaces so they had a choice between mandatory() or mandatory{} they chose the first.
hhafez
@ Micheal, thanks for pointing that out
hhafez
Adding the 1 has kinda made your example redundant, has it not? I can't see any ambiguity anymore.
ICR
You could just do: while do_something() || 1;
Wallacoloo
+10  A: 

Tell me how to interprit the following:

if x ++ b;

Looks silly but...

if( x ) ++b;

or

if( x++ ) b;

or perhaps "x" has an overloaded operator then...

if( x ++ b){;}

Edit:

As Martin York noted "++" has a higher precedence which is why I've had to add the operator overloading tidbit. He's absolutely right when dealing with modern compilers up until you allow for all that overloading goodness which comes with C++.

wheaties
Post increment has a higher priority. So the last one. A better one is if x + b; Is this if (x+b) {;} or if (x) {+b;}
Martin York
or a more commonly recognizable one would be `if x - b`, since the unary minus is more familiar to most than unary plus.
jalf
"interprit" has two 'e's in it.
Jedidja
+2  A: 

One other possible thing to keep in mind: C was created at a time when tape storage was common, so random seek or going backwards through the current file or even other files was not really feasible (which also explains why you have to put some stuff (i.e. forward declarations) before other stuff (i.e. usage of functions) even though the compiler should be able to figure it out on it's own).

Michael Stum
Tape has nothing to do with it. The emphasis in compiler design has always been on left-to-right processing in linear time. Plenty of other languages have forward-declaration rules, not just the tape-era languages.
EJP
A: 

i would love that syntax too, but to avoid parsing ambiguties, must be of this form:

for multiple statements:

if val 
{ 
    doSomething();
    doOthers();
}

for one statement:

if val: 
   doSomething();
Michael Buen
A: 

It's simply a means of ending the condition clause of the statement. Other languages use other means such as a "then" or in Python "if condition :(Followed by a return)" (The : always get me in python I keep leaving them out and get errors than aren't immediately obvious as a result.)

Computer grammars typically like some unique mechanizism to identify the different parts of a statement or expression. It's no better or worst in this respect than any other language. The dangle else issue with C/C++ is an example of ambiguity from a gramatic standpoint and has to be handled as a special case to insure correct operation. (i.e. It adds extra work for the compiler implementor.)

NoMoreZealots
A: 

unless you want significant white space you need to be able to tell when the condition ends in some languages it's () around the condition in some it's the keyword then an if like the one given in the answer

if x * x * b = NULL could be one condition always evaluating to false, one assigning null to *b in the case of (x*x) the compiler has no way of knowing when the condition ends and the following operation begins. So there needs to be an explicit "back marker" for the compiler to know when the condition ends. In C(++), Java, c# and other languages it's () marking the condition in F# it's the keyword 'then' and in still other languages it's a newline/indentation

Rune FS
A: 

Because C allows one to do :

if (x) { // As opposed to java where you need to do if (x == something)
   // your code
}

As you can see above flexibility gives rise to ambiguity as others have shown.

fastcodejava
A: 

The fundamental reason is that C and friends don't have a 'then' keyword so they need another way to delimit the condition-expression. Languages that do, like Pascal and PL/1, don't need the parentheses. Same applies to 'while', where Pascal, PL/1, etc have a 'do'.

EJP