3

Are some of the Haskell idioms of tacit programming translatable to Rust?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
v217
  • 765
  • 1
  • 6
  • 17

1 Answers1

6

You can try to build a macro for that:

#[feature(macro_rules)];

macro_rules! compose_inner(
    ($var:ident, $f:ident) => (
        $f($var)
    );
    ($var:ident, $f:ident $($rest:ident )+) => (
        $f(compose_inner!($var, $($rest )+))
    );
)


macro_rules! compose(
    ($($f:ident )+) => (
        |x| compose_inner!(x, $($f )+)
    )
)

fn foo(x: int) -> f64 {
    (x*x) as f64
}

fn bar(y: f64) -> ~str {
    (y+2.0).to_str()
}

fn baz(z: ~str) -> ~[u8] {
    z.into_bytes()
}

fn main() {
    let f = compose!(baz bar foo);
    println!("{:?}", f(10));
}

The macros probably could be simpler, but that's what I came up with.

But it certainly is not supported in the language itself. Rust is not a functional nor concatenative language after all.

Very similar idiom is method chaining, which is absolutely supported by Rust. The most prominent example, I think, would be iterator transformations:

let v: ~[int] = ...;
let x: int = v.iter().map(|x| x + 1).filter(|x| x > 0).fold(0, |acc, x| acc + x/2);

True, it is not as flexible as arbitrary functions composition, but it looks much more natural and feels much more convenient.

Vladimir Matveev
  • 120,085
  • 34
  • 287
  • 296