Rust itself does not have a compose function. But a closure works fine, so `|fname| to_buff_reader(check_err(open_file(fname)))` would work. If you want to go further, a nightly Rust allows for this kind of construction:
#![feature(unboxed_closures, fn_traits)] // that's why we cannot use stable (yet)
struct Composed<F, G>(pub F, pub G);
impl<F, G, T, U, V> FnOnce<T> for Composed<F, G>
where F: FnOnce<T, Output=U>, G: FnOnce<(U,), Output=V> {
type Output = V;
extern "rust-call" fn call_once(self, args: T) -> V { self.1(self.0.call_once(args)) }
}
impl<F, G, T, U, V> FnMut<T> for Composed<F, G>
where F: FnMut<T, Output=U>, G: FnMut<(U,), Output=V> {
extern "rust-call" fn call_mut(&mut self, args: T) -> V { self.1(self.0.call_mut(args)) }
}
impl<F, G, T, U, V> Fn<T> for Composed<F, G>
where F: Fn<T, Output=U>, G: Fn<(U,), Output=V> {
extern "rust-call" fn call(&self, args: T) -> V { self.1(self.0.call(args)) }
}
fn main() {
println!("{}", Composed(|x| x+3, |y| y*4)(5)); // 32
}Ah, yes it would. Clearly I'm a bit too tired to be writing code, if I've overlooked function application. I suppose it doesn't have to be point-free. =)
Pretty cool, though - thanks for the info.
However, its overloading a custom type to behave like a higher order function, which is a fairly complex piece of code. Most uses of generics are much simpler.
Some people seem to fall back into it a bit when they discover point-free style (and that seems to make up a lot of what you see in mixed-paradigm code). I don't think it'd be controversial to say it's bad practice in any paradigm, so the association of it with FP is kind of like judging web programming by late 90's beginner PHP code (which, at one point in time, did describe a lot of web programming, but it was never good, and we'd like to put that behind us).