The overarching argument in this article seems to be sort of chicken and an egg.
> 4. No experienced developers
Well, with C you need experienced devs that are also EXPERIENCED IN C. You can write C that compiles but is all kinds of incorrect, usually subtly. Any new language that works with the dev on writing correct code or outright refuses to compile with incorrect code (hinting at Rust here) cracks this egg a bit.
> If you want to target some obscure platform, then likely it's assuming you're using C.
Some (most?) obscure platforms offer a fork of GCC, yes. With LLVM frontend becomes less and less relevant. This particular chicken and an egg is being broken with or without a successor to C.
> Any C alternative will be expected to be on par with C in performance. The problem is that C have practically no checks, so any safety checks put into the competing language will have a runtime cost, which often is unacceptable. This leads to a strategy of only having checks in "safe" mode. Where the "fast" mode is just as "unsafe" as C.
This argument is circular. There are indeed some scenarios where you do absolutely need "macro system for assembly" to do some weird shit, but typically that is a relatively small part of the whole project. Unsafe modes help tackle this small need. The argument reads like needing C-ish language for some little parts of your project requires to use C-ish language for the whole project.
> 3. Programmer productivity
This whole argument is weirdly focused. In my experience, a huge chunk of effort is spent on rework. Any language that improves turnaround rate improves productivity on feature level. The argument again assumes that devs manage to produce correct code without turnarounds (which is rare in practice even with highly experienced devs) and therefore any new language would increase turnarounds. Safety and productivity features are usually designed to increase quality without expertise-floor.
I am guilty in a sense, I started a new programming language called C+ and one of the pillars I set was that it should not be an alternative to C (or any other language), in fact it uses Clang as its compiler, most of the points in the article still hold, but I hope it doesn’t stop people from coming up with new ideas and actually implementing them in this field, you don't have to be next big thing to be awesome
I like to program in a C++ subset that's basically C plus a sprinkling of ergonomic quality of life C++ features eg references and generic containers. I think of it as C+.
Is there a modern language with ABI stability that can replace C for that? As in, you can wrap anything with a C API and be sure that it can be called from any other language easily?
The interop story is largely a self-fulfilling prophecy. When you start to explore the edges of C ABI compatibility you discover that er... there's actually no ABI compatibility unless somebody did the work and they never did the work.
Two C implementations on the same CPU with 64-bit integers both, unsurprisingly, think 64-bit integers work the same way - because that was obvious. Now, how about 128-bit integers. Ah, turns out implementation A thought they go (lo,hi) but B thought they're obviously (hi,lo) so these types have different ABI between C implementations...
It's not obvious because most software which cares about Windows also needs the Windows API and so couldn't be non-Windows software, but Windows people have a different rule for how 64-bit works than everybody else, LLP64 versus the usual LP64. And there were other options such as ILP64 they're just all basically dead.
Pretty unconvincing arguments overall. Mostly boils down to "any new language will start as new and not mature". Dismisses any "killer feature" in C's design space. Ignores that there is already a well established C alternative: C++.
But obviously nothing will replace C in the sense that C will cease to exist.
> Ignores that there is already a well established C alternative: C++.
The key point is, C++ added numerous features to C, and at the time, it was the only language occupying that position (or perhaps Objective-C, too?).
Today, a successor to C cannot simply replicate what C++ did. Add too many features, and it will be viewed as a successor to C++ rather than to C (as is the case with Rust and D).
Conversely, keep the additions minimal in order to stay close to C, and you end up in a "red ocean" crowded with Zig, Odin, C3, Hare, Jai, and others.
> My language (C3) is fairly recent, there are others: Zig, Odin, Jai and older languages like eC. Looking at C++ alternatives there are languages like D, Rust, Nim, Crystal, Beef, Carbon and others.
He acknowledges C++ in the first paragraph ...
He's obviously writing this from the point of view of making a case against what he is doing, which is creating a new language (C3). Interesting perspective considering that this was written just before the LLM hype kicked off. It would be interesting to get an update in that context: why create a new language when AIs are going to be the primary user and what would be killer features for AI coding tools to use? It seems languages like Go and Rust are relatively popular targets for using with such tools. C/C++, not so much (other than for code rewrites in Rust).
> Ignores that there is already a well established C alternative: C++.
I don't consider C++ an alternative to C.
I see it as "a more modern language", but there are "even more modern" languages nowadays. The only reason I see to pick C++ instead of something like Rust would be if there are very mature C++ libraries and it is not practical to call them from the newer language. Typically for computer vision (or maybe just linear algebra?), I would still go with C++, probably? But in terms of language, I would pick any modern language over C++ if they do the job.
What about C, then? I use C when I want interoperability. Nothing currently beats C in that domain, as far as I know. I often wrap whatever I have into a C interface just for that.
IMHO, the interesting question about "replacing C" is really this: if you had to design a modern language meant to compete with C's interop story, how would it look like? Not sure if such a language could have memory-safety, for instance? Could such a language be meaningfully nicer than C?
Why are we using C anyhow? I suggest it's mainly because of established codebases although the fact that it has very few dependencies makes it attractive for systems programming perhaps and low-level.
In the case of established codebases the issue is that we don't want to rewrite them because they're huge and not very well designed usually. There are no unit tests or not many and we cannot break ABI compatibility and so on. So change has a risk. Also you're trying to get other developers to agree to the change and they are often in a post-nuclear-war state about other technical decisions and certainly don't want to start another one about some language they don't understand.
What we really need is some way to progressively improve big codebases without having to swallow a huge pill. In other words I need to be able to work a file at a time with something that fits exactly into the build system that is building the C code.
At the moment I'm using ESQL to embed Informix queries - this is a subtly quite good language extension that certainly makes life better except of course that it ties us to a specific expensive database etc etc. As an improvement on C it works in it's limited sphere.
In this huge project there's so much code that it's hard to know what's the right way to do anything and the same solutions have been written again and again in slightly different ways.
Half the libraries have circular dependencies such that they only build with an odd little trick and it's extremely difficult to know the precise reasons why this design evolved or how to begin unpicking those dependencies. Without tests any change could be a disaster.
One established way of improving on C is to use a DSL or something like embedded TCL such that most of the time you're not actually writing C. The current project went the DSL route and it's very very much better than nothing but without a grammar the parser is hard to maintain. I've been on a project using TCL and that was excellent - loading and parsing a config file, for example, is something one almost never really needs to do in C and there are many bits of a program that TCL can do much more reliably and perfectly fast enough.
This ramble is trying to convey that a new language presents a problem to people who have 100 problems already. If you can make it help with those 100 problems then it will win.
Successful example: Converting to Git from SCCS is a huge pain but I've just done it (had to infer changesets from individual file version usernames and dates and times :/ ) but Git is well worth the trouble because it's so much less stressful to make mistakes with and vastly easier to do reviews and so on.
Zig seems to be most prominent C alternative today, well funded, with some high-profile support, excellent engineering and both a loyal fanbase and haters.
That said, as longtime C user, I've been tempted by Jai and Zig and C3, but I am not ready to make the switch yet. The benefits are simply not big enough.
And there is something new that was not apparent in when this article was written: a lot of code is LLM written now, giving old and mainstream language an undeniable advantage. Also, Rust, with the built-in safeguards, is pretty AI assistance friendly.
As some respectable C developer I know says: the issue with the C "killers" is that the people that already know C, have years, decades and experiences they are unwilling to let go. They can jump across any major systems programming project out there and feel at home.
So to win these people you need to have a killer feature that can win them, Rust offers it. The Jai, C3, Zig, etc, do not.
Sure, they are better Cs, but that's not enough to switch.
So eventually, all those C killers will keep growing, among newer system programmers, but not much among seasoned C devs.
For me c is a common ground any feature can be build of. It is very easy to read without much knowledge and has a big base of knowledge around for decades. Anything better than c was in my opinion a WOMBAT. Waste of money brain and Time
C isn't an iota more fundamental than say Modula-2. It's just more popular. And C is very bad at being a low level language. There are plenty of things that you can express in assembly that you just can't do in C. And then the platform ABI won't support it, since C can't support it, and it hampers other languages that don't have C's limitations.
> 4. No experienced developers
Well, with C you need experienced devs that are also EXPERIENCED IN C. You can write C that compiles but is all kinds of incorrect, usually subtly. Any new language that works with the dev on writing correct code or outright refuses to compile with incorrect code (hinting at Rust here) cracks this egg a bit.
> If you want to target some obscure platform, then likely it's assuming you're using C.
Some (most?) obscure platforms offer a fork of GCC, yes. With LLVM frontend becomes less and less relevant. This particular chicken and an egg is being broken with or without a successor to C.
> Any C alternative will be expected to be on par with C in performance. The problem is that C have practically no checks, so any safety checks put into the competing language will have a runtime cost, which often is unacceptable. This leads to a strategy of only having checks in "safe" mode. Where the "fast" mode is just as "unsafe" as C.
This argument is circular. There are indeed some scenarios where you do absolutely need "macro system for assembly" to do some weird shit, but typically that is a relatively small part of the whole project. Unsafe modes help tackle this small need. The argument reads like needing C-ish language for some little parts of your project requires to use C-ish language for the whole project.
> 3. Programmer productivity
This whole argument is weirdly focused. In my experience, a huge chunk of effort is spent on rework. Any language that improves turnaround rate improves productivity on feature level. The argument again assumes that devs manage to produce correct code without turnarounds (which is rare in practice even with highly experienced devs) and therefore any new language would increase turnarounds. Safety and productivity features are usually designed to increase quality without expertise-floor.
Is there a modern language with ABI stability that can replace C for that? As in, you can wrap anything with a C API and be sure that it can be called from any other language easily?
Two C implementations on the same CPU with 64-bit integers both, unsurprisingly, think 64-bit integers work the same way - because that was obvious. Now, how about 128-bit integers. Ah, turns out implementation A thought they go (lo,hi) but B thought they're obviously (hi,lo) so these types have different ABI between C implementations...
It's not obvious because most software which cares about Windows also needs the Windows API and so couldn't be non-Windows software, but Windows people have a different rule for how 64-bit works than everybody else, LLP64 versus the usual LP64. And there were other options such as ILP64 they're just all basically dead.
But obviously nothing will replace C in the sense that C will cease to exist.
The key point is, C++ added numerous features to C, and at the time, it was the only language occupying that position (or perhaps Objective-C, too?).
Today, a successor to C cannot simply replicate what C++ did. Add too many features, and it will be viewed as a successor to C++ rather than to C (as is the case with Rust and D). Conversely, keep the additions minimal in order to stay close to C, and you end up in a "red ocean" crowded with Zig, Odin, C3, Hare, Jai, and others.
He acknowledges C++ in the first paragraph ...
He's obviously writing this from the point of view of making a case against what he is doing, which is creating a new language (C3). Interesting perspective considering that this was written just before the LLM hype kicked off. It would be interesting to get an update in that context: why create a new language when AIs are going to be the primary user and what would be killer features for AI coding tools to use? It seems languages like Go and Rust are relatively popular targets for using with such tools. C/C++, not so much (other than for code rewrites in Rust).
Long-term it almost certainly will. But not in our lifetimes, sure.
I don't consider C++ an alternative to C.
I see it as "a more modern language", but there are "even more modern" languages nowadays. The only reason I see to pick C++ instead of something like Rust would be if there are very mature C++ libraries and it is not practical to call them from the newer language. Typically for computer vision (or maybe just linear algebra?), I would still go with C++, probably? But in terms of language, I would pick any modern language over C++ if they do the job.
What about C, then? I use C when I want interoperability. Nothing currently beats C in that domain, as far as I know. I often wrap whatever I have into a C interface just for that.
IMHO, the interesting question about "replacing C" is really this: if you had to design a modern language meant to compete with C's interop story, how would it look like? Not sure if such a language could have memory-safety, for instance? Could such a language be meaningfully nicer than C?
Disclaimer: I don't know Zig.
In the case of established codebases the issue is that we don't want to rewrite them because they're huge and not very well designed usually. There are no unit tests or not many and we cannot break ABI compatibility and so on. So change has a risk. Also you're trying to get other developers to agree to the change and they are often in a post-nuclear-war state about other technical decisions and certainly don't want to start another one about some language they don't understand.
What we really need is some way to progressively improve big codebases without having to swallow a huge pill. In other words I need to be able to work a file at a time with something that fits exactly into the build system that is building the C code.
At the moment I'm using ESQL to embed Informix queries - this is a subtly quite good language extension that certainly makes life better except of course that it ties us to a specific expensive database etc etc. As an improvement on C it works in it's limited sphere.
In this huge project there's so much code that it's hard to know what's the right way to do anything and the same solutions have been written again and again in slightly different ways.
Half the libraries have circular dependencies such that they only build with an odd little trick and it's extremely difficult to know the precise reasons why this design evolved or how to begin unpicking those dependencies. Without tests any change could be a disaster.
One established way of improving on C is to use a DSL or something like embedded TCL such that most of the time you're not actually writing C. The current project went the DSL route and it's very very much better than nothing but without a grammar the parser is hard to maintain. I've been on a project using TCL and that was excellent - loading and parsing a config file, for example, is something one almost never really needs to do in C and there are many bits of a program that TCL can do much more reliably and perfectly fast enough.
This ramble is trying to convey that a new language presents a problem to people who have 100 problems already. If you can make it help with those 100 problems then it will win.
Successful example: Converting to Git from SCCS is a huge pain but I've just done it (had to infer changesets from individual file version usernames and dates and times :/ ) but Git is well worth the trouble because it's so much less stressful to make mistakes with and vastly easier to do reviews and so on.
Zig seems to be most prominent C alternative today, well funded, with some high-profile support, excellent engineering and both a loyal fanbase and haters.
That said, as longtime C user, I've been tempted by Jai and Zig and C3, but I am not ready to make the switch yet. The benefits are simply not big enough.
And there is something new that was not apparent in when this article was written: a lot of code is LLM written now, giving old and mainstream language an undeniable advantage. Also, Rust, with the built-in safeguards, is pretty AI assistance friendly.
So to win these people you need to have a killer feature that can win them, Rust offers it. The Jai, C3, Zig, etc, do not.
Sure, they are better Cs, but that's not enough to switch.
So eventually, all those C killers will keep growing, among newer system programmers, but not much among seasoned C devs.
Rust made the mistake of thinking it can be low level AND safe. It tried to have the cake and eat it too. That will be its downfall.
Nice ragebait tentative though.