I know I shouldn't be feeding trolls, but why do you think C's syntax is "stupid?" The only thing that really stands out to me as not-so-hot is the prefix pointer declarator.
Posted Jun 29, 2012 23:38 UTC (Fri) by HelloWorld (guest, #56129)
[Link]
I don't know why I'm even responding to this, given that you're calling me a troll without any justification.
Anyway, the main problem with C is its declaration syntax. Let's take a declaration like
void (*signal(int, void(*)(int)))(int);
This is ugly for two reasons. One is that parenthesis are required to distinguish void *(int) from void(*)(int). The other is that the tokens that describe the function's return type are split up: the void(* in the beginning and the )(int) in the end belong together, which is harder to figure out than necessary. Using a postfix pointer declarator fixes the first problem but not the second:
void signal(int, void*(int))*(int);
This is fixable by using another syntax for simple declarations: i int; instead of int i;. That would lead to a declaration like this:
signal(int, *(int)void) *(int) void
This also offers the advantage that the name being declared is always at the beginning of the line. It also makes preprocessor macros that involve declarations easier to write.
Another problem with the C syntax is that in function parameter declarations, foo[] means the same as foo*, while everywhere else it doesn't. People keep confusing arrays and pointer due to this (though the implicit conversion from foo[] to foo* also promotes this).
I also find it ugly that while both :? and if/else exist, there is only a switch statement and not a switch expression.
And just to be clear: the C syntax is actually not the greatest of C's problems. The lack of sane type and module systems is a much greater burden.
Why learn C? (O'Reilly Radar)
Posted Jun 30, 2012 17:48 UTC (Sat) by tjc (subscriber, #137)
[Link]
> signal(int, *(int)void) *(int) void
That's going to be hard to parse. The lexer is going to return a token with the value "signal", but the parser is going to be sitting at the top level without any context in which to evaluate it. If it's not a reserved word then it must be an identifier, but nothing else is known about it without peeking further ahead into the input stream.
Something like this would be more practical:
func signal(int, *(int)void) *(int)void
I personally don't mind that C (and C-like languages) anchor declarations with the type. It's still a left-to-right parse, with the single exception of the type. The "var|func ... <complete return type>" syntax is probably better, but I've been looking at "<type> ..." for so long that it seems natural to me. It also allows you to do things like this:
int i, j;
As far as the foo * vs. foo[] thing, that's not really a syntax problem, it's a semantic problem, given that arrays decay to a pointer to the first element in most (but not all; e.g. sizeof(foo)) cases. I agree that that could be changed, and it would be better in most cases. I usually write array parameters as foo *, just because that's what they really are inside the function.
I'm not aware of the difference between a switch statement and a switch expression, so I can't comment on that. I guess I better start "googling."
Why learn C? (O'Reilly Radar)
Posted Jul 1, 2012 11:15 UTC (Sun) by HelloWorld (guest, #56129)
[Link]
> That's going to be hard to parse. The lexer is going to return a token with the value "signal", but the parser is going to be sitting at the top level without any context in which to evaluate it. If it's not a reserved word then it must be an identifier, but nothing else is known about it without peeking further ahead into the input stream.
I fail to see how conventional C syntax is any better. In a declaration such as foo *bar;, you have exactly the same situation, and to be honest, I don't even see why it's supposed to be a problem.
The only problem I see with this syntax is that it's ambiguous: there's no way to know whether foo(bar)*baz; is a declaration or a statement without looking at the preceding declarations in order to find out whether bar and baz are variables or typedef-names. Alas, conventional C syntax has the same problem in declarations such as the above-mentioned foo *bar;.
It's also fairly easy to disambiguate it using a syntax such as
foo: (bar)*baz;
That would clash with the goto label syntax, as foo: bar; is valid C code. However, this is not a problem: bar; is a statement without effect, so there's no point in writing code like that, therefore a line like that should be parsed as a declaration.
Why learn C? (O'Reilly Radar)
Posted Jul 1, 2012 22:30 UTC (Sun) by tjc (subscriber, #137)
[Link]
I can't think of a situation in C where an expression that begins with a type specifier is anything other than a declaration. I could be overlooking something, but I'm looking at the grammar in appendix A13 of K&R, and I don't see anything.
Why learn C? (O'Reilly Radar)
Posted Jul 1, 2012 22:49 UTC (Sun) by HelloWorld (guest, #56129)
[Link]
> I can't think of a situation in C where an expression that begins with a type specifier is anything other than a declaration.
Uh, so? In a declaration like foo *bar, you still have to know whether foo is a typedef or a variable name in order to know whether it's a multiplication or a declaration.
Why learn C? (O'Reilly Radar)
Posted Jul 1, 2012 23:02 UTC (Sun) by tjc (subscriber, #137)
[Link]
The compiler has this information available to it in the symbol table.
Why learn C? (O'Reilly Radar)
Posted Jul 1, 2012 23:20 UTC (Sun) by HelloWorld (guest, #56129)
[Link]
I know, this is the well-known lexer hack. I still don't see how the syntax I've proposed is supposed to be any more problematic than conventional C syntax.
Why learn C? (O'Reilly Radar)
Posted Jul 2, 2012 20:36 UTC (Mon) by tjc (subscriber, #137)
[Link]
The type specifier in a C declaration acts as a surrogate for the missing 'var' or 'func' keyword, which makes it possible for the parser to recognize the declaration without requesting a lot of extra tokens from the lexer.
Why learn C? (O'Reilly Radar)
Posted Jul 2, 2012 21:23 UTC (Mon) by HelloWorld (guest, #56129)
[Link]
I think that this is only a problem when using top-down parsers. A bottom-up parser should handle this situation easily.
Why learn C? (O'Reilly Radar)
Posted Jul 3, 2012 15:46 UTC (Tue) by tjc (subscriber, #137)
[Link]
Yes, it could be made to work, but it would have to be a backtracking parser, and it would probably be slow. Most bottom-up parsers (such as those produced by bison) are LALR(1), which only has one token look-ahead.
Why learn C? (O'Reilly Radar)
Posted Jul 1, 2012 22:59 UTC (Sun) by tjc (subscriber, #137)
[Link]
I wish there were some way to edit posts after posting so that my mistakes are not permanently recorded for posterity. :)
I should have said, "I can't think of a situation in C where a statement that begins with a type specifier...."
Why learn C? (O'Reilly Radar)
Posted Jul 2, 2012 9:30 UTC (Mon) by nix (subscriber, #2304)
[Link]