27

As Rust gets fleshed out more and more, my interest in it begins to pique. I love the fact that it supports algebraic data types and in particular matching of those, but are there any thoughts made on 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.

Sebastian Graf
  • 3,602
  • 3
  • 27
  • 38
  • 1
    Check out this macro that can derive HKT: https://gist.github.com/14427/af90a21b917d2892eace – CMCDragonkai Jun 30 '15 at 10:52
  • That's impressive! Although the naming of the type variables seems rather arbitrary. I didn't even know that you could have traits with type variables. This is an excellent hack. – Sebastian Graf Jun 30 '15 at 14:37

2 Answers2

25

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.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
centaurian_slug
  • 3,129
  • 1
  • 17
  • 16
16

A language must have "higher kinded types" to support concepts like Functors, Applicatives and Monads. In other words the language must be able to abstract over types that are * -> *, or functions from type to type. Rust does not currently support this level of abstraction. It has been discussed as a possible future direction, but I would not expect it to be a focus anytime soon.

MFlamer
  • 2,340
  • 2
  • 18
  • 25
  • Aye, http://stackoverflow.com/questions/17054978/composition-operator-and-pipe-forward-operator-in-rust – Sebastian Graf Aug 23 '13 at 05:32
  • 2
    C# supports Monads through LINQ. IEnumerable and IObservable are both monadic / linqable. However C# doesn't support higher kinded types so I'm not sure the assertion in this answer is correct. Perhaps you mean something slightly more specific. – bradgonesurfing Apr 22 '14 at 12:59