Live data from Hacker News

The case against a C alternative (2022)

c3.handmade.network

61–70 of 84 posts

Re: The case against a C alternative (2022)

#61
See the author's more recent post "I thought I was building a C replacement. I was wrong": https://c3-lang.org/blog/i_thought_i_was_building_a_c_replac...

Of note, C3 is alive and well, with the latest release (0.8.3) just last week.

I stumbled upon the language earlier this year and love it. I like plain C a lot, but it's a rough experience. Having slices, modules, a strong stdlib and memory management massively improve the experience. The compiler is a 2MB binary compared to the ridiculously huge Rust/Cargo toolchain. I also found LLMs to be really good at writing it, made a simple skill [1] that gets even Claude Haiku to write correct code. Have been using it for several projects and really enjoying it.

[1] https://github.com/ricardobeat/skills/tree/main/c3-lang

Re: The case against a C alternative (2022)

#62
post #41

Rust wasn't made to replace C, C is to be there at low level and as a glue code for everything. Rust was made to replace C++ because the language it's a behemoth, it tries to do everything and the syntax it's a Lovecraftan nightmare, full of legacy incompatibilities. For small games such as Cataclysm:DDA I'd use Go (and for system tools and internet services OFC) and for game engines Rust it's or even GC based langua…

There are times that JIT'd C# out-performs AOT C#, so I'd avoid defaulting to recommending AOT. Assuming that AOT is faster is the same trap that C advocates fall into when thinking that other languages can only ever equal C on speed.

If a language can produce the same machine code (including dynamic patching) as a second language, that second language can at best only equal the runtime characteristics of the first. The development and maintenance costs can be very different.

I am not certain if C (apart from inline assembly) can generate all possible machine code, and some translations can be fragile (autovectorization, e.g.).

Re: The case against a C alternative (2022)

#63

> 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 problem is overstated. There's no safety/performance tradeoff here. Rust has shown that extensive safety checks can be applied at compile time with zero runtime overhead. For a concrete example, checking that an array access is in bounds at runtime does c…

The safety/performance trade is actually, once you think about it, obviously nonsense in principle. All correct solutions will be memory safe so only incorrect programs are unsafe. At that point it can't have better performance, the wrong answer faster is useless - I always come back to Mushroom Office: https://x.com/magdraws/status/1551612747569299458

WUFFS provides strong concrete evidence. A WUFFS image decoder is entirely safe because that was the whole point, but it's also a lot faster because since we've proved this is safe we don't need any of these safeguards and precautions you'd want in languages which aren't sure. We cannot do anything wrong, so there's no need for the compiler to add bounds checks for example never mind Fil-C's "shadow" memory.

Now, WUFFS pays a price for that, it's not a General Purpose Language. You can't write "Hello, World" in WUFFS because it doesn't have strings for the message or I/O to emit the message somewhere. But we should be clear eyed about how much we're paying when we insist we need generality. Not just safety, performance.

Re: The case against a C alternative (2022)

#64
post #11

To me, the value of C is the interop story. 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?

C3, the language created by the post's author has that property:

https://c3-lang.org/language-common/cinterop/

Re: The case against a C alternative (2022)

#65

Earlier quoted context omitted.

There are times that JIT'd C# out-performs AOT C#, so I'd avoid defaulting to recommending AOT. Assuming that AOT is faster is the same trap that C advocates fall into when thinking that other languages can only ever equal C on speed.

If a language can produce the same machine code (including dynamic patching) as a second language, that second language can at best only equal the runtime characteristics of the first. The development and maintenance costs can be very different. I am not certain if C (apart from inline assembly) can generate all possible machine code, and some translations can be fragile (autovectorization, e.g.).

Well indeed, which is why I don't really like talking about the "speed" of a language at all. What really matters is the characteristics of the idiomatic usage.

Re: The case against a C alternative (2022)

#66
post #51

Earlier quoted context omitted.

What would you add to make it suitable? Large SIMD operations that the compiler could split across cores?

I'm definitely the wrong person to ask because my solution was to write Rust. I think the machines C was conceived for are small enough by today's standards that I would not bring a high level language (like C) to the fight, a macro assembler and you'll be fine. For today's much larger machines, use Rust. Oh you've got 16-bit addressing? Chart all the addresses and what you'll use them for on a white board or a big s…

Ironically I think to make the best use of such a small memory window, you'd want a compacting garbage collector. Lots of the 16-bit era BASICs used compacting GC for their strings.

Yes you can statically allocate, but who wants an artificial limitation like "16 strings, 256 bytes each" when some users want 200 strings of 8 bytes and some users want 4 strings of 500 bytes. Static allocation is something you can do when your memory is large compared to your use cases.

Re: The case against a C alternative (2022)

#67

Earlier quoted context omitted.

A couple of examples what's missing from C from a low level perspective: Multiple return values (why can't I have a function using more registers than rax or the stack to push back more values?), sane varargs, stack manipulation (an enabler for coroutines and a lot more) Generally, in an ideal low-level language I wouldn't expect to be hampered because the language is designed for a notional abstract machine that doe…

Also C isn't well suited to a modern multi-core computer. The "fix" in C11 is to just say we have the C++ 11 Memory Ordering Model and here are some built-ins for the ordered atomic operations that implies. Having any model at all is probably most of the value and only one part of the model (consume ordering) is unimplementable fantasy so it could have been much worse, but it's hardly a triumph for a "fundamental" la…

> The "fix" in C11 is to just say we have the C++ 11 Memory Ordering Model and here are some built-ins for the ordered atomic operations that implies.

Isn't Rust's solution mostly the same, just with C++20?

https://doc.rust-lang.org/nomicon/atomics.html

> Rust pretty blatantly just inherits the memory model for atomics from C++20.

Re: The case against a C alternative (2022)

#68
post #50
post #7

To me the case against a C alternative is simple. C is like Math. It is the fundamental high level language. There can be no alternative.. 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.

C has a high level assembly language at its roots - almost every other language does not. That's what makes it fundamental. But someone else could design a different high level assembly language.

C doesn't provide an assembler at all. So if your C implementation provide an assembler that's a non-standard extension. What do you get? It depends, can you use it with a different compiler for the same target? It depends.

So probably you're instead thinking "C is like an assembly language" and that's entirely wrong. The C abstract machine is very weird. No machines exactly like that have ever existed or will ever be built, so you're not programming a real machine. The closest ones were in the 1970s, machines today are very different.

IMO the worst outcome of this "Oh C is just assembler" nonsense is the compound volatile operations.

You probably imagine a line of C like `foo |= 1` ensures `foo` has the LSB set right? You may or may not realise that "Set the LSB of a location in memory" isn't an operation most CPUs have but hey, in C it was a single operation so...

As a hack when compilers got smarter C also has a "volatile" type qualifier, so `foo` can have the type qualifier "volatile" meaning that updates to this variable will definitely happen in memory, the compiler won't just keep `foo` in a CPU register to accelerate things, it has promised to write it back to memory...

So now, `foo |= 1` looks like a single CPU operation which should set the LSB of foo. But of course your CPU probably can't actually do that, so what's really emitted by your C compiler is read foo from memory into a CPU register, set the LSB of that register and then write the whole register back to memory. Which is three distinct operations in sequence, and thus now it can be interrupted by other work and then carry on, despite the fact that meanwhile foo changed...

Oops. The C looks fine, but the machine code generated may introduce a massive bug.

If you do want a language with assembly, Rust provides that. It provides both inline assembler which you can use inside your Rust functions, and bare assembly. Of course that's not safe Rust, but presumably if you wanted to write assembly you were on board with taking the responsibility.

Re: The case against a C alternative (2022)

#69

Earlier quoted context omitted.

> Any new language that works with the dev on writing correct code or outright refuses to compile with incorrect code (hinting at Rust here) I've started writing Rust in the past year and... honestly... I LOVE it. But what kept me away from Rust for a long time is this talking point of rejecting incorrect code which is so obviously wrong it made proponents of Rust sound very cultish to me. Rust cannot prevent incorre…

I resisted Rust for a long time too. I’ve been using C++ since 2002 and always liked it especially with the modern additions. I liked the idea of Rust early on and even tried it in little amounts and it seemed nice enough, but then over time it just felt over complicated for not enough payout. Until I learned it for real and forced myself to overcome the hurdles. Now I love it and find it hard to go back to C++. Why…

How do you feel about pinning in Rust, and how comfortable are you with the aliasing rules of Rust when working with unsafe Rust?

Re: The case against a C alternative (2022)

#70
post #7

To me the case against a C alternative is simple. C is like Math. It is the fundamental high level language. There can be no alternative.. 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.

> 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.

Ridiculous take

Post reply on HN