←back to thread

Four Years of Jai (2024)

(smarimccarthy.is)
166 points xixixao | 3 comments | | HN request time: 0s | source
Show context
pcwalton ◴[] No.43726315[source]
> 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.

replies(4): >>43726355 #>>43726431 #>>43727184 #>>43731326 #
mjburgess ◴[] No.43726431[source]
Well, 1) the temporary allocator strategy; and 2) `defer` kinda go against the spirit of this observation.

With (1) you get the benefits of GC with, in many cases, a single line of code. This handles a lot of use cases. Of those it doesn't, `defer` is that "other single line".

I think the issue being raised is the "convenience payoff for the syntax/semantics burden". The payoff for temp-alloc and defer is enormous: you make the memory management explicit so you can easily see-and-reason-about the code; and it's a trivial amount of code.

There feels something deeply wrong with RAII-style langauges.. you're having the burden to reason about implicit behaviour, all the while this behaviour saves you nothing. It's the worst of both worlds: hiddenness and burdensomeness.

replies(2): >>43726458 #>>43729593 #
hmry ◴[] No.43726458[source]
Neither of those gives memory safety, which is what the parent comment is about. If you release the temporary allocator while a pointer to some data is live, you get use after free. If you defer freeing a resource, and a pointer to the resource lives on after the scope exit, you get use after free.
replies(2): >>43726531 #>>43726581 #
francasso ◴[] No.43726531[source]
While technically true, it still simplifies memory management a lot. The tradeoff in fact is good enough that I would pick that over a borrowchecker.
replies(1): >>43726637 #
junon ◴[] No.43726637[source]
I don't understand this take at all. The borrow checker is automatic and works across all variables. Defer et al requires you remember to use it, and use it correctly. It takes more effort to use defer correctly whereas Rust's borrow checker works for you without needing to do much extra at all! What am I missing?
replies(3): >>43726754 #>>43726792 #>>43729431 #
vouwfietsman ◴[] No.43726754[source]
> The borrow checker is automatic and works across all variables.

Not that I'm such a Rust hater, but this is also a simplification of the reality. The term "fighting the borrow checker" is these days a pretty normal saying, and it implies that the borrow checker may be automatic, but 90% of its work is telling you: no, try again. That is hardly "without needing to do much extra at all".

That's what you're missing.

replies(2): >>43726882 #>>43727057 #
junon ◴[] No.43726882[source]
Maybe I'm spoiled because I work with Rust primarily these days but "fighting the borrow checker" isn't really common once you get it.
replies(1): >>43727070 #
vouwfietsman ◴[] No.43727070[source]
A lot has been written about this already, but again I think you're simplifying here by saying "once you get it". There's a bunch of options here for what's happening:

1. The borrow checker is indeed a free lunch 2. Your domain lends itself well to Rust, other domains don't 3. Your code is more complicated than it would be in other languages to please the borrow checker, but you are unaware because its just the natural process of writing code in Rust.

There's probably more things that could be going on, but I think this is clear.

I certainly doubt its #1, given the high volume of very intelligent people that have negative experiences with the borrow checker.

replies(1): >>43728820 #
1. steveklabnik ◴[] No.43728820[source]
"But after an initial learning hump, I don't fight the borrow checker anymore" is quite common and widely understood.

Just like any programming paradigm, it takes time to get used to, and that time varies between people. And just like any programming paradigm, some people end up not liking it.

That doesn't mean it's a "free lunch."

replies(1): >>43750404 #
2. vouwfietsman ◴[] No.43750404[source]
I'm not sure what you mean here, since in different replies to this same thread you've already encountered someone who is, by virtue of Rusts borrow checker design, forced to change his code in a way that is, to that person, net negative.

Again this person has no trouble understanding the BC, it has trouble with the outcome of satisfying the BC. Also this person is writing Vulkan code, so intelligence is not a problem.

> is quite common and widely understood

This is an opinion expressed in a bubble, which does not in any-way disprove that the reverse is also expressed in another bubble.

replies(1): >>43757323 #
3. steveklabnik ◴[] No.43757323[source]
"common" does not mean "every single person feels that way" in the same sense that one person wanting to change their code in a way they don't like doesn't mean that every single person writing Rust feels the way that they do.