4 ms·
> this study was a victory for higher order functions and ADTs with pattern matching. So, the bread and butter of Haskell? There are few languages that do the
by wyager 10y ago
> this study was a victory for higher order functions and ADTs with pattern matching.
So, the bread and butter of Haskell?
There are few languages that do these two things nearly as well as Haskell. All of them are ML derivatives. Haskell, OCaml, and F# come to mind.
Rust has almost-as-good ADTs, but no higher order functions. A number popular of languages support both of these concepts, but not nearly as natively or conveniently.
- riffraff 10y ago> Rust has almost-as-good ADTs, but no higher order functions. it seems to me Rust has HOF, do you mean they are not as nice as Haskells' ? Why?
- wyager 10y agoCorrect. True functional-style HOFs require passing around arbitrarily-sized heap closures, which doesn't work with rust's memory model. Rust lets you Box closures, but it's very inconvenient compared to treating them as first-class values, so I didn't count it.
- vertex-four 10y agoRust definitely has higher order functions, but it doesn't have higher kinded types required for certain things (like monads). You may have got these confused.
- wyager 10y agoRust has very limited higher-order functions. True functional-style HOFs require passing around arbitrarily-sized heap closures, which doesn't work with rust's memory model. You cannot, for example, have a vector of functions in rust. You can sort of get it with boxed closures, but it's very inconvenient compared to in any of the languages I mentioned. That's why I didn't include it.
- vertex-four 10y agoBoxing things is the way to get arbitrarily-sized things in Rust. I've worked with vectors of closures - it works quite nicely.
- wyager 10y agoIt may work quite nicely by whatever standard you're used to, but it's extremely inconvenient compared to languages that actually make a habit of using HOFs. There's a reason people don't usually use HOFs in Rust outside of a few easily inlinable use cases. The standard library doesn't even have any sort of composition or application operators, because it would be too unwieldy to use.
- vertex-four 10y agoNo, the standard library doesn't contain many of the things that Haskell's does because it's not Haskell, and people haven't really been asking for them like they have a variety of other things. And the reason people don't use them widely is that there's often better designs than passing around closures - lifetimes make useful mutation of closures' environments difficult, Rust largely revolves around mutation, so it's more common to invert the control flow (have functions return a command and interpret it, possibly in a loop, rather than have them take a closure) except in certain self-contained situations. That doesn't change the existence of HOFs.
- wyager 10y agoSounds to me like you're saying the exact same thing I am, which is that HOFs are too inconvenient to be practical in Rust.
- leshow 10y agoRust has first class functions and thus has higher order functions. Iterators have a bunch of higher order functions, map for example: let a = (0..10).map(|x| x*x).collect::<Vec<_>>();
- wyager 10y agoI've already responded a couple times with the same content, but the short of it is that rust HOFs are very limited due to its memory model. True functional-style HOFs require arbitrarily sized closures on the heap, and the only way to get that in Rust is by boxing the closures, which ends up being relatively inconvenient. There's a reason no one uses HOFs in rust outside of trivially inlinable examples like the one you give. There are no composition or application operators in the standard library because it's just too syntactically inconvenient to work with HOFs in the same way you would in a functional language.
- leshow 10y agoIt's true it's not nearly as ergonomic as haskell to pass around functions. You don't necessarily need to box the closure up on the heap in order to store a bunch of functions in say a vector though, it just needs to sit behind some kind of &, &mut, Arc, Rc, Box, etc. I have seen a few hashmaps that store functions as values, in terms of real world uses. You mentioned storing functions (closures here) in a vector, this isn't too much of a stretch I don't think: let x = |c| c * 2; let y = |v| v + 2; let b: Vec<&Fn(_) -> _> = vec![&x, &y]; Definitely not "no higher order functions" as you claimed.
- wyager 10y agoBy the same token, C "supports" higher order functions; you can pass around a function pointer and a pointer to a closure. It's sort of an idiomatic question; HOFs are inconvenient enough in Rust that no one really uses them outside of a few specific cases (like local maps and folds).
- leshow 10y ago