Ask HN: Memory-safe low level languages?
74 comments
·April 27, 2025codr7
There have several attempts at cleaning up C without giving up too much of its simplicity; from what I can see, Zig is the only one even close to reaching critical mass.
A programming language is always going to make some kind of compromise; better at some things, worse at others.
Simplicity/power and safety pull the design in different directions.
hyperbrainer
I don't mind the language having substantially worse "something" as long as it can be a smaller alternative for Rust, for the lack of a better word. Of course, there always needs to be some compromise. I don't mind that. I just have two requirements, and am curious to see how people have tackled that problem.
codr7
Sure, and I'm just as curious.
But at the same time, I'm pretty sure that smaller/simpler is going to mean less safe.
uecker
I think the opposite is true. The Rust philosophy is the idea that a complicated type system should ensure safety. This may work to some degree, but the overall complexity will introduce new issues. I say this as someone who was really excited about type systems in the past, but Rust is ... meh.
tiffanyh
SPARK (Ada) is about as memory-safe as it gets.
andsoitis
I was also going to suggest Spark https://www.adacore.com/sparkpro
There's also this paper, "Memory Safety in Ada, SPARK, and Rust"
https://www.adacore.com/papers/memory-safety-in-ada-spark-an...
tiffanyh
I’ve always found the table comparison (Rust/Ada/SPARK) from that same source to be very informative:
https://blog.adacore.com/should-i-choose-ada-spark-or-rust-o...
fpoling
Vale is interesting, https://vale.dev/
For memory safety compared with Rust it does not use a borrow checker for the price of more checks and extra memory usage at runtime while avoiding GC or even reference counting.
I think this is very interesting trade off. Plus there are plans to implement few interesting ideas that even Rust type system cannot implement while keeping the language simple.
efficax
https://dlang.org/articles/safed.html check out the safed subset of the D language
hyperbrainer
Unfortunately, it seems to use a GC for the safety, which makes it unsuitable for a variety of tasks in the systems programming domain. Seems to me like an alternative to Go more than Rust or C or Zig
fithisux
I second that
mparis
I also love rust and we use it heavily at our startup, but I agree with you and wish there were a mainstream alternative that kept much of the type system, pervasive expressions, and pattern matching while being smaller. I’d accept “very fast” even if it’s not as fast as rust.
One project I’ve seen that I don’t think is particularly active but that I really like the ideas behind is borgo. It compiles to go (thus GC) but is decidedly more rustacean.
Check it out. I hope someone makes something like this wide spread.
PS. I have no affiliation with borgo, just an online fan.
andrewflnr
F-star, which was used to build a verified TLS implementation. https://fstar-lang.org/ Though I guess that's actually on the far side of Rust relative to what you're looking for.
hyperbrainer
The full language is indeed even further ahead of Rust on the spectrum I am looking at, but this seems like a cool effort. I love proof-based languages and dependent types, so this is an absolute win.
What intrigues me quite a bit relative to the main topic of the HN thread is Low[0]
> Low is not only a language subset, but also a set of F* libraries that model a curated set of C features: the C memory model, stack- and heap-allocated arrays, machine integers, C string literals, and a few system-level functions from the C standard library. Writing in Low, the programmer enjoys the full power of F for proofs and specifications. At compile-time, proofs are erased, leaving only the low-level code to be compiled to C. In short: the code is low-level, but the verification is not.
[0] https://fstarlang.github.io/lowstar/html/Introduction.html#t...
thih9
(link from the description, clickable)
> Austral is a new systems programming language. It uses linear types to provide memory safety and capability-secure code, and is designed to be simple enough to be understood by a single person, with a focus on readability, maintainbility, and modularity.
fpoling
Austral GitHub has not received any significant updates for the last two years so I suppose the language development stopped.
markus_zhang
What I dream about is a C with less UB, range based loops, array slicing (supporting negative slicing too), safer and easier string functions (because my pet project is a compiler so gotta write a scanner), pattern matching switch, and maybe a few other stuffs.
Oh maybe less preprocessing black magics :/
shakna
V [0] aims for something along those lines, but I've had a few issues with the safety aspects of the language. Breaking through the checker isn't that difficult.
I absolutely adore Ada [1], but the Pascal-syntax isn't for everyone.
I haven't used it yet, but have been hearing rumblings about Odin [2] a fair bit in these kinds of discussions. I tend to avoid too many symbol-heavy langs, but it's probably still less than Rust (I use a screenreader half the time).
arp242
I just so happened to use Odin a bit this week, and I hit several different problems: two compiler bugs and a stdlib bug. I'm not having a go at the Odin people, just pointing out it's very much an "in development" language with some fairly sharp edges.
n42
I see so much controversy every time V comes up; can someone explain why, without devolving into name calling and personal attacks? What specific design choices or implementation details are contentious, and what legitimate concerns exist beyond interpersonal conflicts?
andrewflnr
Having only watched the discussion: The main problem seems to be grossly inflated claims about its capabilities. As in, the docs say it already does X Y and Z, and when you try them they plainly don't work. And then the creator starts with the personal attacks when you point this out.
detaro
When it launched it proudly claimed to do a lot of things, some of which most people would consider still open research questions. Unsurprisingly, it didn't actually do these things or have a concrete plan of achieving them, and they didn't handle people pointing that out very well. Some other language developers were unhappy about the support V gathered based on these claims vs languages that were further along but honest about what they actually had.
(I have no idea what the current state is)
arp242
> they didn't handle people pointing that out very well
I think that's a fair thing to say. But in all honesty, the people pointing that out were not exactly polite about it, to put it mildly.
I never really looked at V myself and have no opinion, but I do know unpleasant behaviour when I see it and quite a few of the people "pointing out" some of the shortcomings of V were engaging in it.
shakna
V... Overpromised, and underdelivered, on what it could do. Promised complete Type Safety, before the type checker was even implemented, for example.
As for concerns... The main developer is a concern. Hard to trust them to support the language well, with some of the... Well, tantrums. This isn't aimed at a personal attack. But it is very hard to describe their responses in another manner.
This [0] thread on HN covers some of all of the above.
But, probably also important to point out that V and its drama have had dang threaten to ban the topic altogether [1]. There's a lot of drama.
n42
Oh. I fear that I have unwittingly summoned HN demons.
mirashii
https://news.ycombinator.com/item?id=39492680
See this article and the discussions, and if you’re so inclined follow along links in that thread from last time that show folks from the vlang team flaming all over HN.
hyperbrainer
V looks exactly like one of the languages I was talking about. Some controversy about the project, it seems like, but very cool nonetheless. Even if it doesn't actually work like described, the description seems quite interesting.
> But I've had a few issues with the safety aspects of the language. Breaking through the checker isn't that difficult.
What do you mean? Can you "break through the checker" outside of unsafe blocks?
shakna
Its... Buggy. For example, fmt can currently break mutable handles. [0] Or you can modify immutable structures [1].
But there was a time where autofree was just a compiler flag and wasn't actually implemented, even though the author claimed that it was.
Cloudef
[flagged]
carterschonwald
So one kinda cool direction is what they do for the sel4 prject. They have a sequence of high to low level impls and prove correctness wrt spec of the high level etc and prove that each lowering is an implementation of a refinement of the higher level implementation
pron
If you love Rust -- use Rust. Trying to find a language that's just right for you risks it being just that: right for you and few others.
Just remember that even if writing memory-safe programs is your goal, using a memory-safe language is just a means to that goal, and even Rust isn't really memory-safe. Many Rust programs try to achieve memory safety while using a non-memory-safe language (be it C or unsafe Rust), and there's an entire spectrum of combining language features that offer sound guarantees with careful analysis and testing of unsafe code to achieve a safe program. On that spectrum, Zig is much closer to Rust than to C, even though it offers fewer guarantees than Rust (but more than C).
kobebrookskC3
in practice, i don't see rust programs with memory unsafety, but i picked the first zig project that came to mind, bun, and it is riddled with segfaults https://github.com/oven-sh/bun/issues?q=is%3Aissue%20state%3...
hyperbrainer
I love Rust, and will continue to use it. But sometimes it feels like "too much". If you have programmed in Rust, you know what I mean. I want to use and experience a language that is to Rust almost like what C is to C++.
This is primarily an educational exercise to see how people find compromises that work for them, and languages in the same space as Rust using alternative strategies.
JoshTriplett
I've programmed in Rust extensively, and I'm on the Rust language team. I don't quite know what you mean, and I would genuinely like to. If Rust feels like "too much", I'd be interested in knowing what makes it feel that way and how we might be able to improve Rust to avoid that feeling.
Is this something you experience when writing your code, or is this something you experience when reading other people's code?
If it's the former, I'd really love to hear more about those experiences.
If it's the latter, are there particular features that crop up that make code feel like too much?
(To be clear, Rust isn't perfect for everyone, despite our best efforts. And if you want to work with another language, you should! I'm not looking to defend it; your experiences are valid. We'd love to make Rust better, so I didn't want to miss the opportunity to ask, because we so rarely hear from people in the intersection of "I love Rust" and "Rust is too much".)
hyperbrainer
It's hard to pinpoint the problem, because I love and adore Rust. So, thank you for all the work you have put in -- it's a great language.
I feel like my biggest struggle is simply how hard (tedious?) it is to properly work with generics and some more complex applications of traits. Any time I am working with (especially writing, somehow reading is easier) these, I always take an ungodly amount of time to do anything productive.
I am almost certainly sure this is a skill issue -- I am simply not "Rusting" like I am supposed to. Maybe I overuse generics, maybe I rely on traits too much, maybe I am trying to abstract stuff away too much. But this is one of the reasons I want to also explore other languages in the space, especially ones which make it impossible for me to make this so complex.
Don't get me wrong -- all of this complexity is a joy to work with when I can use my brain. But sometimes, it's just too much effort to do stuff, and it feels like I could be getting away with less. Curiously, I never had a problem with the borrow checker, even though people often complaining about how much it forces them to "stop and think".
Another thing is that C, for some weird reason, always feels "lower level" than Rust, and seeing it gives me some sort of weird satisfaction that Rust does not. Maybe it's just a greener grass syndrome, but wanted to mention it nonetheless.
All this said, I want to just emphasise, that despite this shortcoming (if it even is one), if I were forced to choose a language to spend the rest of my life with, I would not be the least bit sad to only ever use Rust again. I absolutely love it.
uecker
I do not see any serious contender to C. And considering that most people developing alternative languages that aim to replace C do not seem to have a good understanding what makes a good system programming language, I also do not see this changing soon. Tooling for memory safety will improve and I expect we will also have something complete in ISO C at some point. But already today, one does not have to write modern C as your parents did, e.g. there is no need to do unsafe pointer arithmetic and many other unsafe features can simply be avoided. Signed integer overflow can be checked at run-time. Only temporal memory safety is missing a good solution that ensures safety, but I do not find this is to be a major problem in my projects (with some discipline about pointer ownership)
pron
Isn't C++ already a serious contender to C? It clearly has not replaced C everywhere, but it's taken over much of C's market. And if C++ could do it, I don't see why another language couldn't do the same (that's not to say that the next language to do that already exists today).
One thing that's important to notice, I think, is that low-level languages' combined market share has fallen sharply since the 1970s, and it doesn't seem that the trend is about to sharply reverse direction. To me that suggests that if a low-level language wants to be more popular than C++, it should focus on low-level programming and shouldn't try to also be a good applications programming language (as C++ has tried to do that, but the overall market share of C and C++ is lower now than it was in, say, 1990), but I could be wrong about that.
pron
If it's for educational purposes and you want to explore various tradeoffs, then you shouldn't necessarily restrict yourself to languages that make similar tradeoffs regarding safety guarantees in the language as Rust. Again, the goal of writing a memory-safe program is understandable, but there's more than one way to achieve that goal when it comes to language guarantees. That doesn't only apply to languages that offer fewer guarantees than Rust, but also to languages that are possibly less low-level (e.g. OCaml, Nim).
But even for educational purposes, using a language with a poor selection of libraries is likely to lead to a bad experience if what you want to produce is working, non-trivial software. Every project includes some "boring" aspects -- such as parsing configuration and data files -- that you won't necessarily enjoy writing from scratch. The overall programming experience is shaped by much more than the design of the language alone.
throwaway81523
You might like Ada as a few people have said. Rust seems kind of niche oriented to me, aimed at programs that for whatever reason don't want to use GC, but ALSO want to use dynamic memory allocation a lot. Ada isn't that great at memory management and mostly aims at embedded programs with fairly simple (maybe just one-time static) memory allocation. In other regards though, it's safer and in some ways simpler than Rust, from what I can tell.
api
Rust can feel like "too much" at times. It's a very feature rich language. But that doesn't mean you have to use every feature. With all feature-rich languages I think that's good advice, since code that does use every single feature often ends up being an unreadable mess. Each feature is there for a certain use case, not for every use case.
Ygg2
> even Rust isn't really memory-safe.
[Heavy citation needed]
Rust isn't memory safe if and only if:
- You messed up writing safe to unsafe interface (and forgot to sanitize your binary afterwards).
- You tripped one of the few unsound bugs in compiler, which either require washing pointers via allocators or triggering some tangle of traits that runs into compiler bugs
- Somewhere in dependecy tree someone did the one of other things.
pron
> You messed up writing safe to unsafe interface (and forgot to sanitize your binary afterwards).
That is the definition of a language not being memory-safe. Memory-safety in the language means a guarantee that the resulting program is memory safe, and that you could not mess it up even if you tried.
Taking that to the extreme, it's like saying that a C program isn't memory safe only if you mess up and have UB in your program, something that C program must not have. But C is not a memory safe language precisely because the language doesn't guarantee that. My point is that there's a spectrum here, the goal isn't memory-safety in the language but in the resulting program, and that is usually achieved by some combination of sound guarantees in the language and some care in the code. Of course, languages differ in that balance.
Ygg2
> That is the definition of a language not being memory-safe. Memory-safety in the language means a guarantee that the resulting program is memory safe, and that you could not mess it up even if you tried.
By your definition no language ever would be deemed safe. Even Java/C# has to interface with C. Or you have to write bindings for C libs/ kernel calls.
> But C is not a memory safe language precisely because the language doesn't guarantee that.
C isn't memory safe because it has 212 different ways to cause memory unsafety. And only offers externals runtime tools to deal with it.
I mean Rust will never be perfect due to Rice Theorem. It doesn't have to be either. It's at close to ideal as you can get, without mandating that programmers are perfect (no language errors) or that everything be written in safe Rust (no C bindings).
This is a well known Nirvana fallacy. E.g. If a cure doesn't cure fatal disease in 100% of cases why not let disease take its course?
jedimastert
Side question and possibly off topic, but is there a formal definition to the term "memory safe"? It seems to mean different things to different people and I'm unsure if I'm just out of the loop and there is an actual definition.
addaon
A memory safe language is one for which (a) there is a subset of programs which can be statically proven to not perform unsafe memory operations at runtime and (b) no programs outside of this subset will be accepted. The set of operations that are considered to be unsafe can vary, but always includes writes to unowned memory, and often includes reads from unowned and/or uninitialized memory.
I am looking for memory-safe languages that can be used for systems/graphics programming. I love Rust, but it often feels like too massive a language with too much stuff going on. Is there a language like C, which is simpler (obviously without all the UB and other problems)?
This is an especially hard ask, given how useful the FP-like features of Rust are, and I find it almost impossible to live without them. Basically, I am looking for a middle ground between C/Zig and Rust.
One such language I have found is Austral[0]. What other such languages are there?
[0] https://austral-lang.org/