Odin looks fascinating, but it's like I can't keep up anymore with C replacements. Nim, zig, rust, odin, bunch of others that are good candidates even for the embedded space.
Will people just be returning to C at some point? If C could just evolve a bit and make some operations much more convenient.
I have "returned" from mainly C++ to mainly C for writing libraries around 2017 (because it's trivial to integrate C code with all those new languages - which can't be said about C++, unless you wrap the C++ code in a C API), and I'm slowly moving to Zig for 'top-level' code. E.g. for the foreseeable future pretty much all my new projects will be Zig at the top and C at the bottom, and AFAIK this is also what most non-trivial Odin projects do.
The nice thing about those new languages is that they don't need a critical mass of users to become useful because they are easy to grasp if you already know C (except for Rust of course), and provide immediate advantages over C while also making it easy to integrate and debug C code (for instance step-debugging from Zig, Odin or Rust into C code 'just works').
I tried Rust a couple of times since 2018 or so, but it's just not my thing. I do maintain Rust bindings for my libraries on the side though, so I'm not completely unaware of Rust's development, but try to follow it from the sidelines watching for interesting new things - unfortunately Rust's development looks like it's fast-tracking C++ of becoming a kitchen-sink language but in much shorter time - and that's on top of the vast 'semantic surface' that Rust needs for being able to build a static memory safety proof. I think this is one area that can't easily be reduced unless the compiler gets a lot smarter (or at least is allowed to peek into called function bodies - which probably wouldn't help the already bad compile times though).
Basically, Rust feels a lot like C++ to me, "just" with static memory safety added on top (and tbf, most historical footguns fixed, but the 'better C' languages did that too).
Both writing (modern) C++ and Rust feels more like type-system puzzle solving than programming, this might be exactly what attracts some people (and would also be very attractive to a more junior me), but personally: when I write or maintain code, the programming language should 'disappear' into the background, and both Rust and C++ don't have that quality, they always want your attention which distracts from the actual problems to solve.
Zig, Odin and even C all have that quality of quietly humming along in the background, you don't think about language features when programming, the code just kinda flows from your brain into the keyboard.
Having said that, I would probably pick Rust for isolated problems and where memory safety is absolutely mission critical (like a sandbox that needs to run untrusted code) - but then use an unsafe language for the code that runs in that sandbox (because what's the point of a sandbox anyway if it can't safely isolate unsafe code).
Great description of the problems of C++/Rust - that puzzle like property attracts a lot of younger engineers and creates a lot of conference talks that hyper focus on the language instead of how it can solve real problems. Scala suffers the same thing in my experience.
C is trivially upstream of everything. Rust is slightly less upstream of everything, in that you have to essentially go through C to do it.
C is also very small and easy to hold in your head, with minimal required dependencies, aside from standard system libraries. Rust typically pulls dozens of dependencies for even small libraries.
These are just tradeoffs. If I were going to build a small library to do something with libcurl, I might do C first then Rust for expanding if required. Same for specialized processing like rasters or computational geometry or even linear programming - all those are C already, and rarely do you find a perfect Rust crate that exposes everything you want.
And unsafe rust is definitely harder than just writing C. It often is easier to write it mostly in C then expose app/higher API level functions to Rust, rather than do the business logic in Rust.
You can write Rust code with no dependencies (not even Rust's standard library) and coders do so regularly when writing code for microcontrollers.
That is one of the primary advantages that distinguishes C and Rust from most languages (which tend to depend completely on a library to do automatic memory management for example).
It is advantageous not only on constrained systems like microcontrollers, but also when interfacing with code written in one of the languages that has a hard dependency on a runtime library to manage memory.
But now you're (almost) back to basically carving out your personal language subset, which is also one of the biggest problems in the C++ ecosystem (it is possible to write 'sane C++', but everybody's sane subset looks slightly different, which massively fragments the library ecosystem and leads to endless frustrating and pointless discussions whether a library should make use of this or that language or stdlib feature).
Not really, most C programs (especially libraries) are written in C89 or C99. GNU-C and all other dialects are generally reserved for when you write an application that won't be interfaced with through code.
> C is also very small and easy to hold in your head
Mostly true during K&R C days, without taking into consideration C compiler dialects outside UNIX V6.
Already during 16 bit home computer days it was already flexible enough with compiler extensions all over the place, that most folks would fail a pub quiz on C.
WG14 had 50 years to improve C's safety story and they hardly cared to move a finger.
Dennis own fat pointers suggestions was never considered, as didn't others, Annex K was a tragedy (yes it had flaws, which could have been improved upon instead of abandon it).
Note that most of safety improvements of Zig and Odin over C were already present in NEWP, PL/I, Modula-2, Object Pascal, among others, so it isn't as this kind of ideas are something completely new that WG14 was never aware of.
They decided this is not something that they care about and that is about it.
I think that if you change the C API officially to introduce one feature you'll realize it's a significant milestone, so you'll end up trying to fix everything else, too, before it's once again locked in stone.
I'm sure a lot of these languages started that way and fell down the same rabbit hole. But that's not necessarily a bad thing. Whether you create a new language or update the old, it's still a step forward.
When it comes to making games I have no interest other than to use C. I am glad and appreciate that I have C skills... even if they are "useless" when in a web or app development role (C#, PHP, etc) --- however, when I tried Odin about 6 months ago (maybe more) I have found my "Better C"
I am one of these people that prefer to have a "one language for all" ... generally speaking. As much as I love C, I know it is not the best for everything. Odin, on the other hand, is a serious contender for this.
Not only am I making a game in Odin (converted away from C99) - I am also creating a Broker Message library and Website in Odin as well.
The Broker system is a rewrite of a C# Windows Service I created, which sends messages and distributes them. For the website, using htmx for the frontend!
Once I finish one of my jobs (I have two) -- I am going to have more time for Odin and these projects. Looking forward to it.
Odin looks fascinating, but it's like I can't keep up anymore with C replacements. Nim, zig, rust, odin, bunch of others that are good candidates even for the embedded space.
Will people just be returning to C at some point? If C could just evolve a bit and make some operations much more convenient.
I have "returned" from mainly C++ to mainly C for writing libraries around 2017 (because it's trivial to integrate C code with all those new languages - which can't be said about C++, unless you wrap the C++ code in a C API), and I'm slowly moving to Zig for 'top-level' code. E.g. for the foreseeable future pretty much all my new projects will be Zig at the top and C at the bottom, and AFAIK this is also what most non-trivial Odin projects do.
The nice thing about those new languages is that they don't need a critical mass of users to become useful because they are easy to grasp if you already know C (except for Rust of course), and provide immediate advantages over C while also making it easy to integrate and debug C code (for instance step-debugging from Zig, Odin or Rust into C code 'just works').
For interest's sake, why didn't you go for Rust? It's really in the wind these days and people also claim it can work on embedded.
I tried Rust a couple of times since 2018 or so, but it's just not my thing. I do maintain Rust bindings for my libraries on the side though, so I'm not completely unaware of Rust's development, but try to follow it from the sidelines watching for interesting new things - unfortunately Rust's development looks like it's fast-tracking C++ of becoming a kitchen-sink language but in much shorter time - and that's on top of the vast 'semantic surface' that Rust needs for being able to build a static memory safety proof. I think this is one area that can't easily be reduced unless the compiler gets a lot smarter (or at least is allowed to peek into called function bodies - which probably wouldn't help the already bad compile times though).
Basically, Rust feels a lot like C++ to me, "just" with static memory safety added on top (and tbf, most historical footguns fixed, but the 'better C' languages did that too).
Both writing (modern) C++ and Rust feels more like type-system puzzle solving than programming, this might be exactly what attracts some people (and would also be very attractive to a more junior me), but personally: when I write or maintain code, the programming language should 'disappear' into the background, and both Rust and C++ don't have that quality, they always want your attention which distracts from the actual problems to solve.
Zig, Odin and even C all have that quality of quietly humming along in the background, you don't think about language features when programming, the code just kinda flows from your brain into the keyboard.
Having said that, I would probably pick Rust for isolated problems and where memory safety is absolutely mission critical (like a sandbox that needs to run untrusted code) - but then use an unsafe language for the code that runs in that sandbox (because what's the point of a sandbox anyway if it can't safely isolate unsafe code).
Great description of the problems of C++/Rust - that puzzle like property attracts a lot of younger engineers and creates a lot of conference talks that hyper focus on the language instead of how it can solve real problems. Scala suffers the same thing in my experience.
C is trivially upstream of everything. Rust is slightly less upstream of everything, in that you have to essentially go through C to do it.
C is also very small and easy to hold in your head, with minimal required dependencies, aside from standard system libraries. Rust typically pulls dozens of dependencies for even small libraries.
These are just tradeoffs. If I were going to build a small library to do something with libcurl, I might do C first then Rust for expanding if required. Same for specialized processing like rasters or computational geometry or even linear programming - all those are C already, and rarely do you find a perfect Rust crate that exposes everything you want.
And unsafe rust is definitely harder than just writing C. It often is easier to write it mostly in C then expose app/higher API level functions to Rust, rather than do the business logic in Rust.
You can write Rust code with no dependencies (not even Rust's standard library) and coders do so regularly when writing code for microcontrollers.
That is one of the primary advantages that distinguishes C and Rust from most languages (which tend to depend completely on a library to do automatic memory management for example).
It is advantageous not only on constrained systems like microcontrollers, but also when interfacing with code written in one of the languages that has a hard dependency on a runtime library to manage memory.
But now you're (almost) back to basically carving out your personal language subset, which is also one of the biggest problems in the C++ ecosystem (it is possible to write 'sane C++', but everybody's sane subset looks slightly different, which massively fragments the library ecosystem and leads to endless frustrating and pointless discussions whether a library should make use of this or that language or stdlib feature).
Well does one write ISO C, GCC C, clang C, AIX C, xyz C?
It is the same issue as well.
Not really, most C programs (especially libraries) are written in C89 or C99. GNU-C and all other dialects are generally reserved for when you write an application that won't be interfaced with through code.
I guess we don't look at the same kind of examples, specially in the enterprise world.
Of course this is true with minor effort.
I'm not doubting rusts benefits, I write rust full time for a reason. Just answering why sometimes C is first.
> C is also very small and easy to hold in your head
Mostly true during K&R C days, without taking into consideration C compiler dialects outside UNIX V6.
Already during 16 bit home computer days it was already flexible enough with compiler extensions all over the place, that most folks would fail a pub quiz on C.
Even more so with C23 as current.
Zig is fun. Rust is a battle.
If I have to choose between 10x safer than C and enjoyable to write, or 12x safer than C and a PITA, I'm choosing Zig.
WG14 had 50 years to improve C's safety story and they hardly cared to move a finger.
Dennis own fat pointers suggestions was never considered, as didn't others, Annex K was a tragedy (yes it had flaws, which could have been improved upon instead of abandon it).
Note that most of safety improvements of Zig and Odin over C were already present in NEWP, PL/I, Modula-2, Object Pascal, among others, so it isn't as this kind of ideas are something completely new that WG14 was never aware of.
They decided this is not something that they care about and that is about it.
Also the often overlooked Ada language.
And Modula-2, now GNU Modula-2 is officially part of GCC full installation.
I think that if you change the C API officially to introduce one feature you'll realize it's a significant milestone, so you'll end up trying to fix everything else, too, before it's once again locked in stone.
I'm sure a lot of these languages started that way and fell down the same rabbit hole. But that's not necessarily a bad thing. Whether you create a new language or update the old, it's still a step forward.
Nice post!
I am sharing a similar experience to you.
When it comes to making games I have no interest other than to use C. I am glad and appreciate that I have C skills... even if they are "useless" when in a web or app development role (C#, PHP, etc) --- however, when I tried Odin about 6 months ago (maybe more) I have found my "Better C"
I am one of these people that prefer to have a "one language for all" ... generally speaking. As much as I love C, I know it is not the best for everything. Odin, on the other hand, is a serious contender for this.
Not only am I making a game in Odin (converted away from C99) - I am also creating a Broker Message library and Website in Odin as well.
The Broker system is a rewrite of a C# Windows Service I created, which sends messages and distributes them. For the website, using htmx for the frontend!
Once I finish one of my jobs (I have two) -- I am going to have more time for Odin and these projects. Looking forward to it.