There are a lot of features thrown into this language that don't seem worth the learning costs they incur. What are the problems you're really trying to fix? Focus on the things that are really important and impactful, and solve them; don't waste time on quirky features that just make the syntax more alien to C programmers.
* `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.
Yeah, Ping, I agree. It reads like they missed the key lesson of C — in Dennis Ritchie's words, "A language that doesn't have everything is actually easier to program in than some that do." And some of the things they've added vitiate some of C's key advantages — exceptions complicate the control flow, constructors and destructors introduce the execution of hidden code (which can fail), and even static overloading makes it easy to make errors about what operations will be invoked by expressions like "x + y".
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.
> Can't make head or tail of what `zero_t` and `one_t` are about, or why they would be useful.
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).
I bike-shedded in this thread about exponentiation. But taking a step back the bigger issue is there are so many poorly justified features thrown in.
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.
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?
Just dropping in to say you are completely correct. It is called "maximum munch" and mandated by the C spec. I recently wrote a toy C compiler and was confused until I learned this.
I suppose ^^ might work, although a little odd because by consistency it would otherwise be the "logical XOR", a mythical operator that doesn't actually make much sense.
Alas, this doesn't deal with the idea of truthyness as a proper logocal XOR would, so it is incorrect in many of the most popular languages, including C, where a value that is true is not always equal to another value that is true. This only works in the much more strongly typed languages, or when you force cast both sides to a boolean with something like !!
Perl has logical xor, which is occasionally useful. I usually reach for it when argument checking, where it makes sense to have either this param or that but not both.
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 :
* `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.