| Exactly the kind of thoughts and insights I need from more of the users. Thank you for pointing out many concerns. > Headers. C++20 modules are left unstable and unused in major compilers there, but it’s a standard. And C is ironically perfect for FFI, as I said, almost every programming language speaks C: Rust WebAssembly API is extern C, JNI in Java, every scripting language, even Go itself talks to OS solely using syscall ABI, foreign-function calls are only possible with Cgo. C was not just an application/systems language for some sad decades. > Big elephants. Since I was in the zoo watching tigers: Mostly three groups of people are served under a language: Application writers, library writers, compiler writers (language itself). I narrowed down and started “small” to see if people writing programs crossing kernel and user space would have more thoughts about C since it’s the only choice. That’s also my job, I made distributed block device (AWS EBS replacement) using SPDK, distributed filesystem (Ceph FS replacement) using FUSE, packet introspection module in router using DPDK. I know how it feels. Then for the elephants you mentioned, I see them more fitted into a more general library and application development, so here we go: > Threading. Async Rust is painful, Send + Sync + Pin, long signatures of trait bounds, no async runtimes are available in standard libraries, endless battles in 3rd party runtimes. I would prefer Go on such problems. Not saying goroutines and channels are perfect (stackful is officially the only choice, when goroutine stacks somehow become memory intensive, going stackless is only possible with 3rd party event loops), but builtin deadlock and race detection win much here. So it just crashes on violation, loops on unknown deadlocks, I would probably go to this direction. > Optimization, hardware. Quite don’t understand why these concerns are “concerns” here. It’s the mindset of having more known safer parts in C, like a disallow list, rather than under a strong set of rules, like in Rust, an allowlist (mark `unsafe` to be nasty). Not making everything reasonable, safe and generally smart, which is surreal. C is still, ironically again, the best language to win against assembly upon an optimizing performance, if you know these stories: - They increased 30% speed on CPython interpreter recently on v3.14. - The technique was known 3 years ago to be applied in LuaJIT-Remake, they remade a Lua interpreter to win against the original handwritten assembly version, without inline caching. - Sub-techniques of it exist more than a decade even it’s in Haskell LLVM target, and they theoretically exist before C was born. It is essentially just an approach to matching how the real abstract machine looks like underneath. > libc. Like I said, C is more than a language. Ones need to switch a new allocator algorithm upon malloc/free, Rust quits using jemalloc by default and uses just malloc instead. Libc is somewhat a weird de facto interface. |
>Modules
Nobody plans to provide other interfaces to oses/middlewares/large established libraries. Economy is just not there.
>Threading
I was not talking about I/O at all. All of that you mention will be miles better in any high level language because waiting can be done in any language. Using threads for computation intensive things is a niche for low level languages. I would go further say that copying stuff around and mutexes also will be fine in high level languages.
>Optimization/Hardware
Is very important to me. I don't know how it was not relevant to your plan of fixing low level language. Here goes couple of examples to try to shake things up.
The strlen implementation in glibc is not written in C. UB just do not allow to implement the same algorithm. Because reading up until memory page end is outside of abstract machine. Also note how sanitizers are implemented to avoid checking strlen implementation.
Pointer provenance that is both present in each major compiler and impossible to define atm. You need to decide if your language goes with abstract machine or gcc or clang or linux. None of them agree on it. A good attempt to add into C standard a logical model of pointer provenance did not produced any results. If you want to read up on that there was HN thread about it recently.
>libc
I am pretty sure I can't move you on that. Just consider platforms that need to use new APIs for everything and have horrendous 'never to be used' shims to be posix 'compatible'. Like you can compile legacy things but running it does not make sense. Games tend to run there just fine because games used to write relevant low level code per platform anyway.