> I've few qualms about writing the server in C.
Bad Unicode support. Lack of cross platform system libraries. Needing to deal with CMake / autotools / whatever. Poor error handling. No built in string, list or map types. No generics. Nullability. No sum types. No option, tuples or multi returns. Generally worse IDE support than a lot of languages. No good 3rd party package ecosystem. The modern idiocy of header files. Memory bugs. Debugging memory corruption bugs. …
I mean, yeah other than all those problems, C is a great little language.
> Bad Unicode support. Lack of cross platform system libraries. Needing to deal with CMake / autotools / whatever. Poor error handling. No built in string, list or map types. No generics. Nullability. No sum types. No option, tuples or multi returns. Generally worse IDE support than a lot of languages. No good 3rd party package ecosystem. The modern idiocy of header files. Memory bugs. Debugging memory corruption bugs. …
You make some good, if oft-repeated, points; but for my product:
1. Bad Unicode support - I'm not sure what I will use this for; glyphs won't be handled by a server program and storage/search of UTF8/codepoints will be handled by the data store (PostgreSQL, if you must know).
2. CMake/autotools/etc - low list of 3rd party dependencies, so a plain Makefile works.
3. Worse IDE support than a lot of languages - not sure what you mean by this. C has LSP support, like every other language. I haven't noticed C support in editors to be worse than other languages.
4. No 3rd party package ecosystem - That's fine, I'm not pulling in many 3rd party packages, so those that are pulled in can be handled with the Makefile and manual updates.
5. The modern idiocy of header files - this confuses me; there is still no good alternative to header files to support exporting to a common ABI. Functions, written in C, will be callable from any other language because header files are automatically handled by swig for FFI.[1]
6. Memory bugs + debugging them - thankfully, using valgrind, then sanitisers in my build/test step makes this a very low priority for me. Not that bugs don't slip through, but single-exit error handling using goto's and cleanups make these kinds of bugs rare. Not impossible, but rare. Having the test steps include valgrind, then various sanitisers reduces the odds even more.
For the rest, yeah, nice to have "No built in string, list or map types. No generics. Nullability. No sum types. No option, tuples or multi returns. ", but those are optional to getting a product out. If C had them I'd use them, but I'm not exactly helpless without them.
The downside of writing a product in C, in 2025, isn't in your list above.
========================================
[1] One of my two main reasons for switching to C is because the product was so useful to paying clients that they'd like more functionality, which includes "use their language of choice to interact with the product.". Thus far I've hacked in solutions depending on which client wanted what, but there's limits to the hacked-in solutions.
IOW, "easily extendable by clients using their language of choice" is a hard product requirement. If it wasn't a hard requirement they can continue using the existing product.