11 ms·
Would you mind sharing some thoughts about fil-c? AFAICT its claims mostly check out so besides implementation details (GC?) it seems directionally good.
by mi_lk 2mo ago
Would you mind sharing some thoughts about fil-c? AFAICT its claims mostly check out so besides implementation details (GC?) it seems directionally good.
- steveklabnik 2mo agoI'll come back and say some more in a bit, but in short: I like the idea of fil-c, but I also have some issues. I think it's overall a good and interesting project, but with some caveats.
- norman784 2mo agoNot OP, but AFAIK one big issue with FIL-C it does the checks at runtime, adding overhead, don't quote me on this, but IIRC is around 20% slower.
- josephg 2mo ago2x slower and 4x less memory efficient were the numbers I heard a year or so ago. Reaching within 20% of full native performance while using a garbage collector sounds too good to be true. Do you have any actual benchmarks?
- deleted 2mo ago[deleted]
- steveklabnik 2mo agoOkay so: in general, as a rule of thumb: anything that makes stuff have more memory safety is good. And experiments towards that end are also good. What I do not like, primarily comes down to how the project is talked about and marketed. First, because it promotes an "us vs them" mindset, instead of a "we're all trying to improve memory safety" mindset, and second, because in doing so, it also overstates its case. These things are sort of intertwined. Let's talk about the overstatement first. Fil-c has its own definition of memory safety that is slightly different than others. For example, I saw this recently: #include <stdlib.h> #include <stdio.h> #include <string.h> struct User { char name[8]; int is_root; }; int main(int argc, char*argv[]) { struct User* user = malloc(sizeof(struct User)); strcpy(user->name, argv[1]); if (user->is_root) { printf("I am root!\n"); } else { printf("I am not root :(\n"); } return 0; } This, when invoked with "012345678" passed in, will print "I am root!". In my understanding, this is deliberately allowed. But beyond corners like this, fil-c's author will go on about "Rust has unsafe as a hatch, fil-c does not" while if you control-f for "zunsafe_" on https://fil-c.org/stdfil https://fil-c.org/stdfil you get ... escape hatches. The author regularly erases the difference between "traps at runtime" and "is prevented at compile time", which are legitimate tradeoffs where one or the other may be better depending on what you're doing. But they're presented as either equivalent, or one is superior, and I find this muddles the discourse. The performance issues also tie into this, "add a GC" is absolutely a valid way to handle these sorts of issues, but it is not the same thing as what Rust does. And that's okay! But presenting it as purely superior means that it's just hard to talk about. Speaking of muddling the discourse, the author regularly trolls on X, providing tons of bad faith arguments and generally trying to rile up a "fil-c vs Rust" war that I think reduces our ability to talk about these differences in a calm, engineering focused context. Finally, due to its design, fil-c is effectively Linux only. That's great for Linux, but many people also use other systems, and so it is not a meaningful option for them. Anyway, after saying all that: I still think that it is a good project, and that it should exist and continue to be worked on. I just wish that the heat was turned down, and people could talk about the various approaches and their tradeoffs without turning it into a culture war.
- pron 2mo ago> it promotes an "us vs them" mindset, instead of a "we're all trying to improve memory safety" mindset But you did the same thing when, on the spectrum that ranges from C to ATS, with Zig, Rust, and Java somewhere in the middle (though all closer to C than to ATS), you declared the exact compromise that Rust makes "table stakes"! [1] Zig improves on C's memory safety when it comes to spatial safety, possibly the more impactful kind, so it, too, could be part of the "we're all trying to improve memory safety", yet you exclude it. You're trying to draw some hard line that passes exactly between Rust and Zig on the C to ATS spectrum, and I'm trying to say that that line isn't there (your attempt at a definition of delineating safe and unsafe code also applies to C). Obviously, C, Zig, Rust, Java, and ATS all make very different tradeoffs, all of which may be more or less attractive to different people and in different circumstances, but there is no sharp line, at least not one that is meaningful enough to be "table stakes". Your personal inclinations place a premium on the things Rust offers and Zig doesn't while mine are the opposite, but I make no claim to universality. I'm happy to accept that not everyone shares my aesthetics and can understand why some people prefer Rust, but those claims to or hints at universality annoy me (as they did when they were made by Haskellers, and I actually find Haskell's aesthetics quite pleasing), as they are simply unsupported. I've spent a lot of time studying formal methods and software correctness in general (https://pron.github.io https://pron.github.io) and if there's one thing we know in that field is that things are never that simple (and, bringing this back to this posts topic, even something like incremental compilation can contribute to program correctness). (Now, you may argue that you're only talking about "memory safety" and not correctness in general, but what gives memory safety value is that violations are causes of many dangerous vulnerabilities; but once, say, Java eliminates all of them, 100% of bugs/vulnerability - which are still numerous - will be caused by other problems, all potentially avoidable with ATS, so why isn't ATS table stakes? Of course, the answer is cost, but all the languages on the spectrum differ in their costs.) [1]: I assume that you meant Rust's compromise, because you implied that Zig doesn't pass that bar but Rust does.
- Maxatar 2mo agoThere's a distinction between claiming something is objectively better, which is what Fil-C claims with respect to its "idea" about memory safety compared to Rust... and claiming a personal preference for one approach versus another approach, which is what OP is saying about their own personal preference about how Zig reduces errors compared to how Rust reduces errors. It is absolutely possible that one language might actually have an objectively better approach to memory safety than another, and in such cases it is usually possible to argue for this using sound technical or empirical arguments. But the way the author of Fil-C presents their arguments it often comes across in a kind of antagonistic manner, like he has a chip on his shoulder.
- josephg 2mo agoMy main problem with Fil-C is that it combines the worst parts of C with the worst parts of a GC language. In a language like C (or Zig), you need to manually manage memory. This makes programming a lot more complex, and it's really easy to accidentally mess up. Especially in large projects which have a lot of separate modules. The biggest advantage of using a garbage collector is that you don't have to think about freeing memory. The GC automatically frees objects when they're no longer referenced. This makes programming much much easier. The downside of using a garbage collector is that it hurts performance at runtime. GC languages are slower and use more RAM. Fil-C is the worst of all worlds here. Like C, it forces you to manually manage your own memory. But you still pay the performance cost of having a runtime garbage collector. And that cost is (apparently) really high. The only performance numbers I've seen showed ~2x worse CPU performance and ~4x worse memory performance. There's no way Fil-C can compete with C, Zig and Rust for performance. So with Fil-C, you have a language that's much slower than C, and much more difficult to program in than C#, Java, Go or Typescript. Fil-C still has some wonderful uses. Fil-C could be a fabulous debugging tool for C programs. It could be a wonderful teaching tool if it had nice visualisations on top of the GC's view of the world. And it could be a great way to run legacy C code. But it's not a "rust killer". Fil-C programs run too slowly to be able to compete head to head with rust. And Fil-C doesn't offer the language benefits of a GC that you get in C#, Go, and friends. It seems like a really bad deal.
- archargelod 2mo ago> GC languages are slower This is not necessarily true. It depends on a language, e.g. Go is slow, Nim[0] is extremely fast with conventional GC and slightly faster with ARC/ORC[1]. GC programs can be faster than manually managed ones in some cases. It's just manual memory management gives you more control of where and when free is called. And a good type system is a privelege that gives Nim more control with destructors. Another scarecrow of safe languages is GC pauses, which is also not a thing in Nim, see table in [2]. [0] - https://nim-lang.org/ https://nim-lang.org/ [1] - https://nim-lang.org/blog/2020/10/15/introduction-to-arc-orc-in-nim.html https://nim-lang.org/blog/2020/10/15/introduction-to-arc-orc... [2] - https://nim-lang.github.io/Nim/mm.html https://nim-lang.github.io/Nim/mm.html