Search code examples
rusttacit-programming

Is tacit programming possible in Rust?


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


Solution

  • 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.