Most active commenters
  • the__alchemist(3)
  • Ygg2(3)
  • int_19h(3)

←back to thread

Things Zig comptime won't do

(matklad.github.io)
458 points JadedBlueEyes | 17 comments | | HN request time: 1.593s | source | bottom
Show context
no_wizard ◴[] No.43744932[source]
I like the Zig language and tooling. I do wish there was a safety mode that give the same guarantees as Rust, but it’s a huge step above C/C++. I am also extremely impressed with the Zig compiler.

Perhaps the safety is the tradeoff with the comparative ease of using the language compared to Rust, but I’d love the best of both worlds if it were possible

replies(5): >>43744960 #>>43745201 #>>43745418 #>>43745573 #>>43749228 #
ksec ◴[] No.43745418[source]
>but I’d love the best of both worlds if it were possible

I am just going to quote what pcwalton said the other day that perhaps answer your question.

>> I’d be much more excited about that promise [memory safety in Rust] if the compiler provided that safety, rather than asking the programmer to do an extraordinary amount of extra work to conform to syntactically enforced safety rules. Put the complexity in the compiler, dudes.

> That exists; it's called garbage collection.

>If you don't want the performance characteristics of garbage collection, something has to give. Either you sacrifice memory safety or you accept a more restrictive paradigm than GC'd languages give you. For some reason, programming language enthusiasts think that if you think really hard, every issue has some solution out there without any drawbacks at all just waiting to be found. But in fact, creating a system that has zero runtime overhead and unlimited aliasing with a mutable heap is as impossible as finding two even numbers whose sum is odd.

[1] https://news.ycombinator.com/item?id=43726315

replies(4): >>43745462 #>>43745760 #>>43745791 #>>43746930 #
the__alchemist ◴[] No.43745760[source]
Maybe this is a bad place to ask, but: Those experienced in manual-memory langs: What in particular do you find cumbersome about the borrow system? I've hit some annoyances like when splitting up struct fields into params where more than one is mutable, but that's the only friction point that comes to mind.

I ask because I am obvious blind to other cases - that's what I'm curious about! I generally find the &s to be a net help even without mem safety ... They make it easier to reason about structure, and when things mutate.

replies(4): >>43745891 #>>43745963 #>>43746263 #>>43747347 #
1. rc00 ◴[] No.43745891[source]
> What in particular do you find cumbersome about the borrow system?

The refusal to accept code that the developer knows is correct, simply because it does not fit how the borrow checker wants to see it implemented. That kind of heavy-handed and opinionated supervision is overhead to productivity. (In recent times, others have taken to saying that Rust is less "fun.")

When the purpose of writing code is to solve a problem and not engage in some pedantic or academic exercise, there are much better tools for the job. There are also times when memory safety is not a paramount concern. That makes the overhead of Rust not only unnecessary but also unwelcome.

replies(3): >>43745915 #>>43746004 #>>43747477 #
2. the__alchemist ◴[] No.43745915[source]
Thank you for the answer! Do you have an example? I'm having a fish-doesn't-know-water problem.
replies(1): >>43746854 #
3. Ygg2 ◴[] No.43746004[source]
> The refusal to accept code that the developer knows is correct,

How do you know it is correct? Did you prove it with pre-condition, invariants and post-condition? Or did you assume based on prior experience.

replies(3): >>43746128 #>>43746298 #>>43749589 #
4. yohannesk ◴[] No.43746128[source]
Writing correct code did not start after the introduction of the rust programming language
replies(1): >>43746376 #
5. edflsafoiewq ◴[] No.43746298[source]
One example is a function call that doesn't compile, but will if you inline the function body. Compilation is prevented only by the insufficient expressiveness of the function signature.
6. Ygg2 ◴[] No.43746376{3}[source]
Nope, but claims of knowing to write correct code (especially C code) without borrow checker sure did spike with its introduction. Hence, my question.

How do you know you haven't been writing unsafe code for years, when C unsafe guidelines have like 200 entries[1].

[1]https://www.dii.uchile.cl/~daespino/files/Iso_C_1999_definit... (Annex J.2 page 490)

replies(1): >>43746850 #
7. int_19h ◴[] No.43746850{4}[source]
It's not difficult to write a provably correct implementation of doubly linked list in C, but it is very painful to do in Rust because the borrow checker really hates this kind of mutually referential objects.
replies(1): >>43749579 #
8. int_19h ◴[] No.43746854[source]
Basically anything that involves objects mutually referencing each other.
replies(1): >>43746946 #
9. the__alchemist ◴[] No.43746946{3}[source]
Oh, that does sound tough in rust! I'm not even sure how to approach it; good to know it's a useful pattern in other langs.
replies(1): >>43747522 #
10. charlotte-fyi ◴[] No.43747477[source]
Isn't the persistent failure of developers to "know" that their code is correct the entire point? Unless you have mechanical proof, in the aggregate and working on any project of non-trivial size "knowing" is really just "assuming." This isn't academic or pedantic, it's a basic epistemological claim with regard to what writing software actually looks like in practice. You, in fact, do not know, and your insistence that you do is precisely the reason that you are at greater risk of creating memory safety vulnerabilities.
11. int_19h ◴[] No.43747522{4}[source]
Well, one can always write unsafe Rust.

Although the more usual pattern here is to ditch pointers and instead have a giant array of objects referring to each other via indices into said array. But this is effectively working around the borrow checker - those indices are semantically unchecked references, and although out-of-bounds checks will prevent memory corruption, it is possible to store index to some object only for that object to be replaced with something else entirely later.

replies(2): >>43747732 #>>43748790 #
12. estebank ◴[] No.43747732{5}[source]
> it is possible to store index to some object only for that object to be replaced with something else entirely later.

That's what generational arenas are for, at the cost of having to check for index validity on every access. But that cost is only in comparison to "keep a pointer in a field" with no additional logic, which is bug-prone.

13. Cloudef ◴[] No.43748790{5}[source]
>unsafe rust Which is worse than C
14. Ygg2 ◴[] No.43749579{5}[source]
Hard part of writing actually provable code isn't the code. It's the proof. What are invariants of double linked list that guarantee safety?

Writing provable anything is hard because it forces you to think carefully about that. You can no longer reason by going into flow mode, letting fast and incorrect part of the brain take over.

15. lelanthran ◴[] No.43749589[source]
Rust prevents classes of bugs by preventing specific patterns.

This means it rejects, by definition alone, bug-free code because that bug free code uses a pattern that is not acceptable.

IOW, while Rust rejects code with bugs, it also rejects code without bugs.

It's part of the deal when choosing Rust, and people who choose Rust know this upfront and are okay with it.

replies(1): >>43754844 #
16. bigstrat2003 ◴[] No.43754844{3}[source]
> This means it rejects, by definition alone, bug-free code because that bug free code uses a pattern that is not acceptable.

That is not true by definition alone. It is only true if you add the corollary that the patterns which rustc prevents are sometimes bug-free code.

replies(1): >>43756056 #
17. lelanthran ◴[] No.43756056{4}[source]
> That is not true by definition alone. It is only true if you add the corollary that the patterns which rustc prevents are sometimes bug-free code.

That corollary is only required in the cases that a pattern is unable to produce bug-free code.

In practice, there isn't a pattern that reliably, 100% of the time and deterministically produces a bug.