// bonus doc bug: "with" hasn't been introduced yet
void ^?{}( VLA & vla ) with ( vla ) { // destructor
The syntax for redefining ++ or -- (which already seems spurious) is even more opaque. S & ?+=?( S & op, one_t )
Other features, like left-to-right declaration syntax and postfix function calls, seem to have no use except to make one programmer's code harder for another programmer to understand. Then they throw in the rest of the kitchen sink, with all of C++'s overloading and polymorphism and inheritance plus both kinds and traits. The result is even more complex and even more surprising (in a bad way) to actual C programmers than C++ or for that matter APL. If not for the absence of templates, I'd say Cforall's complexity is a strict superset of C++'s.If I wanted a direct C replacement with minimal improvements, I'd try D or Zig. If I wanted a systems programming language that had more differences but fewer surprises, Rust or Nim. The last thing I'd want is something that's both more baroque (rococo?) and less known than any of those.
I think that in the case of C2 it’s still a language that will rely on the same paradigms as C, whereas C-for-all is more of a “kitchen sink” style of language that moves very far from C in how the natural code solutions are. Just the small change adding destructors and constructors is a feature with huge impact on how data will be managed (for better and for worse)
(Full disclosure: I have contributed to C2 in the past and I’m working on the C3 lang which is feature and syntax-wise based on C2 but goes further: https://www.c3-lang.org )
https://news.ycombinator.com/item?id=9829133
Anyway, it seemed like an interesting project the last time I looked at it but Rust wound up getting all my attention.
Their key points seem to be that Rust (and other existing languages) lack backwards compatibility and have different memory management strategies. Lumping Rust in with GC languages is confusing.
Whether either of those things matter is another story. From using TypeScript, I'm personally inclined to believe that a superset of a difficult language can't solve all of the underlying problems, while a totally new language can.
I personally want a better stdlib for C; fix the defiancies of <string.h>, removing the global locales (changing function behaviors according to LC_* was a really, really bad idea[0]), etc...
Does anyone know of an alternative stdlib for C?
[0] https://github.com/mpv-player/mpv/commit/1e70e82baa9193f6f02...
For starters: implicit coercion is out; weak type aliasing is out; automatic binary serialization of aggregate types is out; etc.
In the age of Go and Rust, which already have a hard time finding niches, I don't really think there's any room for a language like this. And on the other hand, from a research standpoint, it's probably a lot more interesting to build a new language from the ground up.
Some experimental compiler builds (Calypso) can compile D for use with C++ libraries as complex as Qt.
You can start porting your D project to C by using DPP- it allows you to #include C headers within D- and use macros. Putting "extern(C):" at the top of your file let's you interoperate between C and D.
Andrei Alexandrescu wrote Modern C++ Design, and is the co-captain of D. The captain of D created the first end-to-end C++ compiler.
I think they're missing the point of why people use C - there's no magic. It's pretty much the wysiwyg of high level -> asm. If you want a systems language with magic there's C++. If you want a safe one there's Rust.
Personally if I were going to make C better, I'd add a better macro/template feature so you don't have to write generic code as a define block with slashes all over, something like Go's defer, and some low level stack unwinding support. Maybe tuples as struts with numbered fields, but no magic syntax sugar. And that's it. No crazy operators, type theory things, or anything that doesn't do exactly what the code says. Because then it's not C.
But what do I know?
Strict aliasing and weak typing say hello.
> wysiwyg of high level -> asm
Except neither GCC nor Clang compile even remotely predictable ASM. It's easier to predict OCaml assembly output than the GCC's one.
Everyone with this opinion needs to read this[0].
This is why it was not rare to see defense company or Airbus financing those research.
To make the time even harder, in that niche space, you already have decent enough languages like Nim and Zig etc.
So yeah, the market is really pretty saturated, I don't even have time and project idea to try them all, let alone bring them to work.
How are tuples different from structs? You can pass around and return whole structs (not pointers) just fine in plain C.
Underscores in int literals should probably be proposed to the ISO committee for C itself. A similar concept works successfully in OCaml. (Binary literals would also be useful).
I've never felt that C lacked sufficient control structures, and the new ones proposed here just seem like they will confuse people. What specific problem is each new control feature trying to solve?
Adding exception handling (to C) seems like an actively bad idea. What are the semantics? How does unwinding work exactly and how would it interact with resource allocation?
Coroutines are today successfully handled in libraries, so I'm not sure what you gain by adding them to the language.
Already announced in 2007: http://lambda-the-ultimate.org/node/2181
> While C++, like C∀, takes an evolutionary approach to extending C, C++'s complex and interdependent features (e.g., overloading, object oriented, templates) mean idiomatic C++ code is difficult to use from C, and C programmers must expend significant effort learning C++.
the "significant effort" for learning C++ pays off (financially), while this certainly does not.
It not as hard as rust where the binary is not built if a rule is violated.
If it is then it can be made part of the build process and the effect will be the same: the binary will not get built if the rules are violated.
They want the productivity improvement of C++ without leaving behind 2-way compatibility.
MISRA-C's idea of safety is banning function pointers.
---
Rule 104:
This is there to prevent the address of a function from being calculated at run time. i.e. the use of pointer arithmetic to calculate the value of a pointer to function is prohibited.
The reason is that an error in the calculation of the address could lead to a system failure.
Rule 105:
This is to ensure that a function pointer is only used to access functions that have the same return value type and formal parameter list. i.e. the type of the function pointer and the function to which it points must be the same.
The reason for this is to keep the use of the pointer consistent. If it is not, it is possible for the programmer to supply the wrong number of parameters when a function call is made, as it might not be clear which function the pointer is pointing at.
---
FWIW I have used function pointers twice in my career. From my personal experience you can improve readability by avoiding function pointers.
The features page feels extremely painful to read. It took me at least two minutes to even begin to make sense of the first section: "Declarations", then an explanation of Tuple, immediately followed by:
int i;
double x, y;
int f( int, int, int );
f( 2, x, 3 + i ); // technically ambiguous: argument list or comma expression?
Tuple isn't mentioned again until seven or so lines after its explanation. After reading further, I realise they aren't linked in any way, but this was confusing at first. I thought I was missing something major about the syntax. [ y, i ] = [ t.2, t.0 ]; // reorder and drop tuple elements
I don't know what this even means.
If this: [ i, x, y ] = *pt; // expand tuple elements to variables
pulls out tuple elements into variables, and this: x = t.1; // extract 2nd tuple element (zero origin)
accesses tuple elements: then what is "reorder and drop" and why does the combination of the above two behaviour result in an ostensibly different third behaviour?It gets worse the further down the page I try to understand. Very claustrophobic and presented as a mish-mash of syntax examples. I can't see how this is any better than C's syntax, honestly. What C would benefit from is a better baked-in stdlib, OR an easily available, downloadable, lib of helper functionality that doesn't require any modifications to existing code (eg. when I want a hashtable in an already-established project, I don't want to modify my existing structs!)
I think an improved C would be quite useful, but you really should be careful with what you include it, and keep the language simple. A lot of functionality feels like added because it could be added (WTF are nested routines). This way lies worse C++.
In particular, I wouldn't look too much into what C++ does. Rather, I would look into what Go, Rust and Zig do. `?{}` and `^?{}` are clearly inspired by C++ constructors and destructors, but that's not the only way (in fact, it's a rather bad approach if you want to keep things simple). For instance, you could avoid having constructors and require full initialization for structures with destructors. Hypothetically, it could look like this.
struct Point {
int x;
int y;
};
struct Point new_point(int x, int y) {
return { .x = x, .y = y };
}
Meanwhile, C-for-all is mostly missing actually useful features. Slice types (https://www.drdobbs.com/architecture-and-design/cs-biggest-m...) would be huge, but they are nowhere to be seen. Vtable dynamic dispatch? Missing. Borrow checker? Missing. Module system (maybe a stretch, but...)? Missing.In C99 it looks like this:
struct Point {
int x;
int y;
};
struct Point new_point(int x, int y) {
return (struct Point) { .x = x, .y = y };
}I guess ancient C compilers would do a memory copy on return, but there are various optimizations in "newer" compilers which remove redundant copies, and structs up to 16 bytes or so are passed in registers anyway (via the 64-bit Intel and ARM ABI conventions).
struct Point a = new_point();
struct Point a2 = a;
Assuming `struct Point` has a destructor, this would move `a` into `a2`, and prevent accesses to `a` after `a2` assignment, as `a` is no longer considered to be alive at this point. C++ has a wrong default of cloning instead of moving, but a new language could fix that.Last I checked, memory safety for C (e.g. fat pointers with bounds checking) seems to impose a ~60% performance overhead on traditional processors (with hardware support it could be much less.) In many (most?) cases, that overhead is worth the improvements in reliability and security.
For certain applications (probably anything network facing) I'd probably want to compile the whole OS, libraries, and software base with -safe.
We aren't in as dire a situation here in Canada as Australia [0] seems to be, but there's a reason it was so difficult to serve that Huawei extradition.
[0]: https://www.news.com.au/national/victoria/news/its-a-police-...
- A C developer must find as low friction as possible to use it.
- It will look alike C as much as possible.
- Will not bring a big semantic/syntax departure
- Not bring any novel stuff or Gc. BetterC is C as will be written by the BEST of the developers with the BEST practiques applied, and removed (as much as possible) the most obvious mistakes or ill-advised features.
- BetterC must be/have a transpiler. Even if that break for a while perfect behaviors it provide a way to cleanly upgrade things forward. Because BetterC is well writen C, the user will be encouraged to use it with the confidence of be in the ecosystem.
- BetterC must be incorporated (eventually?) as a front-end in a C compiler (like LLVM). So is like have "strict on" available.
- This mean is better if is backed by the community as a long, step-by-step goal of C. This also mean must be done for people that actually love/like C, just want it to be better.
- Must provide a set of blessed libraries like unicode strings, arrays, numbers, dates, etc. If not in-built at least included so most that use C as all-around lang not get out (similar in this case as Rust)
- Must encourage rewrite of critical pieces of code, despite zero-cost of FFI with C.
- Fix stupid syntax issues like dangling else. This is the "easiest" part I think.
- Find the biggest issues of the langs/common libraries and kill them.
- NOT ALLOW STUPID BY DEFAULT. Bring the "unsafe" keyboard here. No excuses!
- Bring sane macros.
- Bring AGTD, pattern matching, for ... in ..., and hopefully, fast fast compile times.
x = t.1; // extract 2nd tuple element (zero origin)
Zero-based indexing in a programming language is not necessarily a dealbreaker but is always a worrying sign about how hard the designer thought their design through. (This does not apply to the design of C, which does not have zero-based indexing; arrays are indexed by offset rather than "from zero".) These are structs with fewer names and less ceremony involved. Why would the first field be "field 0"?Obviously CForAll has a learning curve advantage over Zig, being based on C directly, but for any readers not aware, I'd say, also check out Zig.
C interop is beautiful. My primary language is on the Erlang Virtual machine, and it's easier to write FFI using Zig than it is to write it in C.
Other aspects of its design look good however.
The primary advantage of C is that, and this just parphrasing a Linus Torvald's quote - it was developed at a time when computers weren't that powerful and so it's very close to assembly such that a proficient C programmer knows exactly what's going on under the hood.
I can't say the same for Rust or C++ which both spit out an enormous amount of code thanks to monomorphisation and all the other "zero cost" abstractions they employ.
Yet Another Fucked Up Attempt To Make C What C Is Not
C is not “unsafe” as in “flawed”: it’s designed to fill certain gaps. Its syntactic stability through the decades - as well as its “minimalism” (for a lack of better word) - are among its most important features.
Personally I have been having an hard time trying to figure out why there’s some part of the industry that desperately tries to change what C is in a way or the other.
...but probably I’m just an old Valley fart. Apologies for the rant.
This might be the reason.
They might well use UWaterloo's CS Club infrastructure, which can withstand enough traffic. For instance, the FOSS mirror at https://mirror.csclub.uwaterloo.ca
Plain C ought to be considered a legacy language and not used for new code. There is zero reason to prefer it over whatever style of C++ you'd like. If you want procedural struct-based C++, you can have that, but gosh, don't write C.
Sorry, but it does.