Rust RAII is better than the Haskell bracket pattern
1–10 of 156 posts
Re: Rust RAII is better than the Haskell bracket pattern
#2Therefore the RAII style wouldn't really work in Haskell. The current bracket approach is still better than RAII in Haskell.
That said, the ST-style trick of a phantom type variable is pretty well-known. Unfortunately not many people knew the same trick can be used for non-ST as well. I feel like as a community we should be encouraging this style more often.
UPDATE: I wrote the original comment with the incorrect assumption that drop functions will always be called in Rust. This is wrong. Please see child comments.
Re: Rust RAII is better than the Haskell bracket pattern
#3Re: Rust RAII is better than the Haskell bracket pattern
#4Would be interesting to know why memory leaks are possible in Rust, if RAII is so deeply integrated into language.
It has no such static checking because it was deemed to reduce expressiveness, while not impacting memory safety.
Re: Rust RAII is better than the Haskell bracket pattern
#5Would be interesting to know why memory leaks are possible in Rust, if RAII is so deeply integrated into language.
fn leak() {
// Create a 1KiB heap-allocated vector
let b = Box::new(vec![0u8; 1024]);
// Turn it into a raw pointer
let p = Box::into_raw(b);
// Then leak the pointer
}
Obviously that's kind of blatant, but there are more subtle ways to leak memory. Memory leaks aren't considered unsafe, so even though they're undesirable the compiler doesn't guarantee you won't have any.Reference cycles when using Rc are a big one, but generally it's pretty hard to cause leaks by accident. I've only run into one instance of leaking memory outside of unsafe code, and that was caused by a library issue.
Re: Rust RAII is better than the Haskell bracket pattern
#6The thing is that, in Haskell, even when you attach a function to run during destruction, the runtime doesn't guarantee that the function will be called promptly, or even at all. Rust drops (runs destructor and deallocates) values as soon as they go out of scope; C++ too. In Haskell you depend on the whims of the GC, which makes RAII unusable. (The Haskell approach of not guaranteeing destructors being called does ha…
The linked post is interesting, because I didn't realise "RAII is a much better way of managing resources than destructors" was controversial. It absolutely is, RAII is fast, predictable, and flexible. It's also one of the tradeoffs some languages make to achieve more flexibility in their design by enabling performant automatic garbage collection that doesn't require perfect escape analysis.
Re: Rust RAII is better than the Haskell bracket pattern
#7The thing is that, in Haskell, even when you attach a function to run during destruction, the runtime doesn't guarantee that the function will be called promptly, or even at all. Rust drops (runs destructor and deallocates) values as soon as they go out of scope; C++ too. In Haskell you depend on the whims of the GC, which makes RAII unusable. (The Haskell approach of not guaranteeing destructors being called does ha…
There's also no guarantee for Rust/C++ destructors to be called. It's certainly less of an issue then depending on the GC to being called, but if you need absolute correctness, then you shouldn't rely on the destructors.
Re: Rust RAII is better than the Haskell bracket pattern
#8The thing is that, in Haskell, even when you attach a function to run during destruction, the runtime doesn't guarantee that the function will be called promptly, or even at all. Rust drops (runs destructor and deallocates) values as soon as they go out of scope; C++ too. In Haskell you depend on the whims of the GC, which makes RAII unusable. (The Haskell approach of not guaranteeing destructors being called does ha…
> The thing is that, in Haskell, even when you attach a function to run during destruction, the runtime doesn't guarantee that the function will be called promptly, or even at all. There's also no guarantee for Rust/C++ destructors to be called. It's certainly less of an issue then depending on the GC to being called, but if you need absolute correctness, then you shouldn't rely on the destructors.
If you allocate an object on the heap with `new` then its destructor isn't called automatically unless you make it so through some other mechanism, but GP comment clearly want claiming that.
There are some situations where objects with block scope do not have their destructor called e.g. `_exit()` called, segfault, power cable pulled out. But in that sense nothing is guaranteed.
Re: Rust RAII is better than the Haskell bracket pattern
#9Would be interesting to know why memory leaks are possible in Rust, if RAII is so deeply integrated into language.
Granted, the ownership/borrowing semantics of rust make this a lot harder, but anything that uses Rc/Arc can easily fall prey to it — you can use those to create a reference cycle.
Re: Rust RAII is better than the Haskell bracket pattern
#10Python's "with" clause, and the way it interacts with exceptions, is the only system I've seen that gets this right for the nested case.