Search code examples
functional-programmingrust

Does/Will Rust support functional programming idioms?


I love the fact that Rust supports algebraic data types and in particular matching of those, but are there any plans to support other functional idioms?

  1. E.g. is there a collection of the standard filter/map/reduce functions in the standard library, and more important, can you chain/compose them in a syntactical pleasing manner [1]?

  2. Since there are already elegant means for ADTs to be used, how about monads, in particular some syntactic sugar for them?

[1] Haskell got (.) and (>>>), C# extension methods and optionally LINQ, D has unified function call syntax.


Solution

  • Rust doesn't have HKT's, but its iterators do support coding in a functional style with higher order functions (HOF) like map, filter, fold etc., with convenient chaining.

    The details differ compared to functional languages- those are usually garbage collected, whereas Rust programs deal with memory management in a deterministic manner, similar to C++ RAII - as part of the program's flow.

    To allow efficient chaining, the individual HOF's return composable lazy expression templates, and you can turn the final result into data (allocating and evaluating in one step) by finishing with .to_owned_vec() or .collect() or whatever.

    In some situations this isn't necessary, the expression-template returned is an iterator itself and that might be sufficient. For example, you can iterate over that with a for loop, or pass it as an argument to a generic function.

    See:

    Similar patterns are possible in both C++11 (with additional libraries) and Rust. Rust's generics aren't quite as powerful as C++ templates, but immutability by default, expression-oriented syntax, polymorphic lambdas, and two-way type inference give it a feel slightly closer to a functional language.

    Regarding 'extension methods' and uniform call syntax, Rust allows a similar 'open-world' way of organizing code. You can add impls with more methods to any type anywhere within a library or program, or extend existing types from other libraries by implementing your own trait's methods on them.

    This makes it easier to use the chainable method calling style than in C++ (i.e. less need to modify or derive types).

    Bear in mind a lot of Haskell's idioms are to do with purity (e.g. the IO monad, lenses..), and Rust is multi-paradigm, not pure-functional. You can have a pure function for the benefits of referential transparency at the program level, and yet its implementation is simplified by mutable local variables.