Hacker News new | ask | show | jobs
by vvanders 3701 days ago
The one thing that's tripping me up on Rust from doing everthing in a purely functional way is the way closures are dealt with. I really hate the idea that I'm going to need to Box::new() every closure I pass around if I want to return it from a function or store it. Even simple move closures can't be cloned and makes some things that are simple in Haskell/Elm/etc much more painful.

Don't get me wrong, great language but I'm a but dubious of the 1:1 porting story here.

3 comments

Closures in other languages like Haskell, JavaScript and Python (and almost certainly Elm too, I've never used it and hence don't know for sure) are similar to the `Rc<Fn(...) -> ...>` type in Rust. In fact, if absolutely necessary, one could probably use that everywhere.

Stuff like this is one of the trade-offs in Rust: control over exactly how closures behave (if allocations are necessary, if virtual calls are necessary when calling it) is balanced with/detracts from how much typing one needs to do to get them to work.

Duh, dunno why I'd forgotten Rc.

I'm still not a huge fan of the extra allocation(and chance for cycles) but I stand corrected that it does work, kudos.

My number one gripe is missing TCO because I find writing recursive functions more natural for many problems. We can't have everything.
There's an RFC being actively worked on that will make it easier to pass around unboxed closures.
That sounds nice, I spent a good chunk of today hacking on a FRP implementation similar to Elm and the ability to not clone + a few other things around closures kept painting me into a corner each time. I even went as far to drop down to std::mem::transmute_copy, but when I hit a Box<Fn(A) -> B> the type has already been erased and I can't recover it.

It seems like if you have no references in your closure you should be able to pass them around as a value-type(with generics, of course). From what I can tell without that there's a whole range of FP patterns that just aren't representable in Rust because of it.