Live data from Hacker News

Rust RAII is better than the Haskell bracket pattern

snoyman.com

151–156 of 156 posts

Re: Rust RAII is better than the Haskell bracket pattern

#151
post #40

Earlier quoted context omitted.

I am always impressed by what the ocaml/Haskell people can do compared to my language of choice (scheme). Iirc Oleg Kiselyov implemented proper delimited continuations in ocaml as a library, without touching the runtime or compiler. Something similar has been done in Haskell. I doubt fully dependent types can be implemented in Haskell without extra help by ghc. There has been lots of work in the area, and last time I…

>Iirc Oleg Kiselyov implemented proper delimited continuations in ocaml as a library, without touching the runtime or compiler. To clarify this, the library you're talking about implements most of the functionality in C, reusing the runtime's exception mechanism. So it doesn't require any upstream change to compiler or runtime, but it also can't be implemented in pure OCaml.

Hmmm. I remembered incorrectly then. The bytecode version is possible in pure ocaml, but for native it apparently needs C.

For Haskell it is however possible. There is a neat paper by among others Kent Dybvig.

Re: Rust RAII is better than the Haskell bracket pattern

#152

Earlier quoted context omitted.

> when many C++ and Rust programs are about to end, they spend the last few cycles uselessly deallocating memory that would've immediately been freed via _exit(2) thank god they do this. how many times did I have to manually force linux to release sockets because badly coded C programs which opened sockets forgot to release them causing them to hang up for ~5 minutes after the process ended. With proper RAII classes…

Do you mean orphaned sockets, stuck in FIN_WAIT? Surely what objects are are meant to do is call shutdown(2) syscall - or shutdown(3) C library function - on the socket in their destructor or whatever to prevent that. But I don't think the same applies for memory, once the process is destroyed the kernel should reclaim all memory in the process page tables automatically. Otherwise you'd end up with a pretty trivial w…

> Surely what objects are are meant to do is call shutdown(2) syscall - or shutdown(3) C library function

well, the problem with non-RAII solutions is that you depend on the whims and talent of the programmer to call shutdown at some point. With a RAII solution like in C++ or Rust you know that if your socket opened successfully, a call to close will necessarily be issued.

Re: Rust RAII is better than the Haskell bracket pattern

#153
post #15

Something to keep in mind - linear types are on their way[1], with exactly this usecase in mind. Simon Peyton Jones gave an excellent presentation on the topic[2], briefly discussing exceptions, as well as giving a mention to ResourceT and the phantom type solution in the article (described as channel-passing). [1] https://arxiv.org/abs/1710.09756 [2] https://www.youtube.com/watch?v=t0mhvd3-60Y

I'm not convinced the current linear types proposals actually let us solve the problem, in the presence of exceptions. I may very well be missing something, or it may be that exceptions are rare enough that leaking resources until garbage collection only when an exception occurs is fine in practice.

FWIW Rust doesn't consider leaking an object to be unsafe. In fact, there's a std::mem::forget() function that can be used to do precisely this. Before Rust 1.0 it was marked `unsafe`, but it was determined that the existence of Rc allowed for creating retain cycles in safe Rust, and "fixing" this was prohibitively complicated, and since it was possible to leak values in safe rust, std::mem::forget() was therefore determined to not be unsafe. This was also when "leaking values isn't a violation of safety" was turned into an actual principle, as opposed to just a hunch that a bunch of people had, and the one API that relied on leaking being unsafe was removed (this was the API for scoped threads, which was marked as unstable right before 1.0 came out, and subsequently an alternative stable safe API for doing scoped threads was hashed out in the crates ecosystem).

Re: Rust RAII is better than the Haskell bracket pattern

#154

Earlier quoted context omitted.

Do you mean orphaned sockets, stuck in FIN_WAIT? Surely what objects are are meant to do is call shutdown(2) syscall - or shutdown(3) C library function - on the socket in their destructor or whatever to prevent that. But I don't think the same applies for memory, once the process is destroyed the kernel should reclaim all memory in the process page tables automatically. Otherwise you'd end up with a pretty trivial w…

> Surely what objects are are meant to do is call shutdown(2) syscall - or shutdown(3) C library function well, the problem with non-RAII solutions is that you depend on the whims and talent of the programmer to call shutdown at some point. With a RAII solution like in C++ or Rust you know that if your socket opened successfully, a call to close will necessarily be issued.

Maybe I'm being dumb here, but with RAII in C++ at least, doesn't shutdown() and then close() have to be called on the socket by the programmer explicitly in the destructor for the class?

Re: Rust RAII is better than the Haskell bracket pattern

#155

Earlier quoted context omitted.

> Surely what objects are are meant to do is call shutdown(2) syscall - or shutdown(3) C library function well, the problem with non-RAII solutions is that you depend on the whims and talent of the programmer to call shutdown at some point. With a RAII solution like in C++ or Rust you know that if your socket opened successfully, a call to close will necessarily be issued.

Maybe I'm being dumb here, but with RAII in C++ at least, doesn't shutdown() and then close() have to be called on the socket by the programmer explicitly in the destructor for the class?

> doesn't shutdown() and then close() have to be called on the socket by the programmer explicitly in the destructor for the class?

yes, the class has to be written only once - and I have personnally never had to write it except in that one group project in school, since I use libraries that handle it - e.g. boost.asio or Qt Network.

If you are in C, even if you use an abstraction layer, you have to remember to call a _free / _destroy-like function every time you write some code that uses sockets.

Re: Rust RAII is better than the Haskell bracket pattern

#156

Earlier quoted context omitted.

Maybe I'm being dumb here, but with RAII in C++ at least, doesn't shutdown() and then close() have to be called on the socket by the programmer explicitly in the destructor for the class?

> doesn't shutdown() and then close() have to be called on the socket by the programmer explicitly in the destructor for the class? yes, the class has to be written only once - and I have personnally never had to write it except in that one group project in school, since I use libraries that handle it - e.g. boost.asio or Qt Network. If you are in C, even if you use an abstraction layer, you have to remember to call…

Point being, the same is not true for virtual memory. You could leave the memory deallocation out of the destructors, and it is all going to be returned to the OS instantly on _exit().
Post reply on HN