3 ms·
About higher order functions: putting effects in the type forces you to make a distinction between map and mapM. You can't unify them because one takes a -> b a
by cousin_it 11y ago
About higher order functions: putting effects in the type forces you to make a distinction between map and mapM. You can't unify them because one takes a -> b and the other takes a -> m b. Same for any other higher order function, you have to write two versions (or more if you don't have HKT).
About memory safety: can you give an example where a naive implementation of catchable exceptions would break memory safety? I know about RecoverSafe but it seems to be solving a different problem (marking types whose logical invariants are preserved in case of panic).
- Manishearth 11y ago> forces you to make a distinction between map and mapM. You can't unify them because one takes a -> b and the other takes a -> m b. You have the same distinction in exceptions? One map would bubble the exception, the other would internally catch and exclude. You don't have to write two versions, map still works for cases with and without Result, but it will not have the additional behavior of excluding errors. You want that additional behavior, hence you write mapM; just like you would in C++. > About memory safety: can you give an example where a "naive" implementation of catchable exceptions would compromise memory safety? I know about RecoverSafe but it seems to be solving a different problem (marking types whose logical invariants are preserved in case of panic). There's an example in the rfc: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md#background-what-is-exception-safety-in-rust https://github.com/rust-lang/rfcs/blob/master/text/1236-stab... In Rust logical invariants are used to enforce memory safety. If the destructor of something within a vector panics, that might result in an invalid vector. There's a pattern colloquially called "pre pooping your pants" which would help in this specific case (http://cglab.ca/~abeinges/blah/everyone-poops/ http://cglab.ca/~abeinges/blah/everyone-poops/), but not in general. Writing unsafe code in Rust involves careful bookkeeping if you want to be sure the code is safe; and that goes out the window when the rug can be pulled out from underneath you any time.
- cousin_it 11y agoWell, that example doesn't use catch, so it doesn't really tip the scales on catchable vs uncatchable exceptions. It does show that you have to be extra careful when making function calls from unsafe blocks, and that destructors are especially error prone. I agree with all that :-)
- Manishearth 11y agoRecover is basically catch, it shows how a panic can leave something in a invalid and unsafe state, which can be accessed after recovery (without recover you wouldn't be able to access it). :)
- cousin_it 11y agoYou can see the invalid state even without catch/recover, e.g. from destructors that are called during unwinding.
- Manishearth 11y agoAh, I see. Right, that works in this case, but it doesn't work in all -- you can come up with a situation where the destructor is fine but the recovery can lead to arbitrary unsafe things.