An interesting exercise might be to figure out how to do the Golang feature set, or some useful subset of it, in a C-compatible or mostly-C-compatible syntax.
I do like the returnable tuples, though, and the parametric polymorphism is pretty nice.
I suspect it's the same problem C++ has/had (C++11 fixed it) with bools (see the safe bool idiom [0]). Basically treating a type like an integer (arithmetic object) and boolean (logical object) at the same time is problematic (especially for a "system" type meant for extending implicit system behavior). Because then I can do `if(BoolObject < 70)` when I only meant for `if(BoolObject)` to work (where "BoolObject" is some object evaluating to a bool, and by evaluating I mean coercing/casting).
Here it looks like they approached it by making 0/1 (effectively C's false/true) different types and relying on their simpler/more-powerful type system (e.g. because they don't have to worry about C++'s insane object system). Not a terrible idea if they were otherwise actually sticking to their goal of "evolving" C (most of their features are radical departures from the language like exceptions). C++11 solved it by clarifying how implicit explicit casting [sic] of rvalues works in certain keywords (which I strongly doubt anyone can say was the simpler way of solving the problem).
[0] https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool
I don't have the feeling that the authors appreciate the appeal of C as a simple language that maps closely to hardware features.
This is a big random collections of extensions that piqued some implementor's fancy. There is seemingly no effort at narrowing down to the cleanest or most important ideas. It totally kills the clean, simple aesthetics of the the base C languge.
WHAT?
discrim = b² - 4ac; // Standard notation
float discrim = pow(b, 2) - 4*a*c; // C
float discrim = b \ 2 - 4*a*c; // C∀
I would argue that these are presented here in descending order of readability.Also its typing rules are really complicated; apply it to two integers and magically you are thrown into the floating-point world where you can never be completely certain of anything, but if you use an unsigned exponent then you stay safely in integer-land.
int a = 1;
int *b = &a;
int c = a ** b;
// Am I casting b to an int (returning it's address) and exponenting it or am I derefrencing b and multiplying it's result with a?'||' and '&&' are distinct tokens in C as far as i know, i.e. not handled as two consecutive '|'s or '&'s.
So your example would unambiguously be parsed as "a to the b:th power". Whereas the other case would need explicit parens:
int c = a * (*b);
Similar example for &: int a = 1;
int b = 1 && a; /* 1 LOGICAL_AND a */
int c = 1 & (&a); /* 1 AND address of a */Hmm I'm pretty sure practically every programming languages have it. It usually looks like "!=" or "<>".
The even more obscure logical XNOR is usually denoted "==" or "="
I assume there's a double asterisk there, and it's being eaten by the formatter?
float discrim = b*b - 4*a*c;
Using pow for a small integer power is a no-no: less efficient and less accurate.I agree that \ is an awkward choice. A Fortran-like double asterisk ∗∗ is out because of ambiguity with pointers; single caret ^ out because it is already reserved for bitwise xor. Maybe double caret ^^ or asterisk-caret ∗^ could be used? That would read okay :
double discrim = b^^2 - 4*a*c;
double discrim = b*^2 - 4*a*c;Using pow for a small integer power compiles into the exact same code: https://godbolt.org/g/CjoHdJ
Using pow for a small integer power is a no-no: less efficient and less accurate.
I think you missed the point.
* `if` / `case` / `choose` improvements look fine, though not that important.
* Exception handling semantics aren't defined.
* `with` is pointless and adds gratuitous complexity to the language.
* `fallthrough` / `fallthru` / `break` / `continue` are all just aliases for `goto`. It's not obvious to me that we really need them.
* Returnable tuples look very nice.
* Alternative declaration syntax looks like a nightmare. If we were redesigning C from the ground up, a different declaration syntax might be better, but mixing two syntaxes is a terrible, terrible idea.
* References. Why? They only add confusion.
* Can't make head or tail of what `zero_t` and `one_t` are about, or why they would be useful.
* Units (call with backquote): gratuitous syntax, unnecessary and confusing.
* Exponentiation operator: gratuitous and unnecessary.