Hacker News new | ask | show | jobs
by NobodyNada 4 days ago
Not the parent, but: I strongly dislike this framing of "Fil-C is better than Rust" or "Rust is better than Fil-C". This is apples-to-oranges; users will almost never be comparison-shopping between the two because they address almost entirely different problems.

There are roughly two categories of Rust user:

1. People who are using Rust for application development. Most of these users write zero unsafe blocks in their careers. For these users, "memory safety" was probably not a strong reason to pick Rust, because there are a wealth of other memory-safe application development languages out there.

2. People who are using Rust for systems programming (i.e. programming under resource or environment constraints). These users may write unsafe for performance reasons, or to do things like hardware MMIO; and they're using Rust over C/C++ either for security or just because the tooling is nicer.

The first category of user is unlikely to consider C for application development in this decade; they're going to be comparing Rust against Go or Java or Node.js. Fil-C solves the security problem of memory safety, but it does not free the developer from the difficulty of having to manually write memory-safe C code; their program will just crash if they get it wrong.

The second category of user cannot use Fil-C because of its performance overhead, runtime requirements and/or lack of escape hatches for MMIO/FFI.

Where Fil-C does shine is for legacy application software written in C. Here, it's a free lunch: a way to harden the massive amount of existing software without an expensive rewrite. I would love to see distros shipping pizlonated coreutils, ffmpeg, systemd, curl, sudo, postgres, etc., anything that has a big attack surface, but does not need to be memory-unsafe.

This is a problem I care about a lot, and your work here is truly a monumental advancement in the field. Comparisons to Rust sell it short by inviting endless debate on problems largely tangential to Fil-C.

1 comments

I’ve never said that Fil-C is better than Rust full stop.

I have articulated the specific ways that Fil-C is better.

And I’ve articulated the specific ways that Rust is better. You’ve enumerated some of those reasons from your perspective, though I disagree on the details.

I like those kinds of conversations. We shouldn’t shy away from them as a community. They help us grow a shared understanding of the tech

Let's not shy away then. What details do you disagree on?

P.S. Also fan of your work. Competition is always good.

Rereading your post, I think I just disagree on two things:

I don’t think Rust users can be trivialized into the “two kinds” that you list, and if one of the kinds is “app developer” then I bet you there are apps where Fil-C’s value proposition is exactly right, except just the fact that Fil-C is so new and immature. Say you want to ship a native UI. Using GTK from fil-C is fantastic.

And I specifically disagree with:

> it does not free the developer from the difficulty of having to manually write memory-safe C code; their program will just crash if they get it wrong.

When I write new code in Fil-C, I just lean into the GC all the way, which makes programming in C and C++ so much nicer. I don’t ref count, I don’t use smart pointers, I don’t free and I don’t delete. It makes these languages so much nicer!

Also, Fil-C’s guarantee that it will panic on OOB or if a race goes badly means I spend basically zero time debugging memory safety issues. The reliability of the failures totally changes the dev experience for the better.

That’s subjective obviously. Some folks swear by type systems like Rust’s to catch as many issues as possible. That’s just not how I roll.

All of that said - the reason to use rust and not Fil-C is performance and memory usage. Fil-C isn’t there yet, except for maybe a small handful of cases (like BLAKE3 and xzutils, where the overhead is basically zero for some reason … we’ll probably because I did a lot of compiler opts and sometimes you get lucky and they sort of all hit)

> That’s subjective obviously. Some folks swear by type systems like Rust’s to catch as many issues as possible. That’s just not how I roll.

Yeah, I like it. I also like not caring about dangling pointers, UAF, and other things, not even because of security. These are just bugs that are not fun to debug.

But I get the appeal of the freedom of C++. Especially if you deal with FFI and low level stuff, Rust either forces you to write safe wrappers (good investment long-term, but not fun to do), or just use lots of unsafe, in which case there's no benefit.

This, and there's also cargo which is convenient.

> When I write new code in Fil-C, I just lean into the GC all the way, which makes programming in C and C++ so much nicer.

Then it's no longer C/C++. More like C++/CLI maybe. And it probably gets tricky with FFI. Anyway, keep it up on making the world a safer place :)

> When I write new code in Fil-C, I just lean into the GC all the way, which makes programming in C and C++ so much nicer. I don’t ref count, I don’t use smart pointers, I don’t free and I don’t delete. It makes these languages so much nicer!

Sure, GC's are nice which is why so many langs have them, but that removes the deterministic allocation performance which most C/C++ programmers want (and many times need). Why not just use something like Go then? You have a much richer stdlib available out of the box.

> Also, Fil-C’s guarantee that it will panic on OOB or if a race goes badly

Fil-C as currently implemented does not guarantee panics on unsafe accesses due to races. You dodge the problem by using a private definition of safety under data race that permits program executions nobody would expect.

I define memory safety in terms of capabilities, which is a mainstream definition.

The worst that can happen in a race is that you read or write an object that would have been accessible even in the absence of races.

The thing that makes races hard to debug in C or C++ is memory corruption; that doesn’t happen in Fil-C

I’m having a hard time understanding how these two things can be true at once. Just because the capability exists that somewhere in my program a valid pointer to a piece of memory might exist (what I understand accessible to mean), doesn’t mean that a particular write to that memory location under a data race that tears a pointer is valid. The data race may make a pointer that would never algorithmically appear in the program in the absence of races, and thus make writes that invalidate invariants that should have been preserved. It seems to me this still provides a way to corrupt memory in a difficult to debug way just like C. Am I missing something?