IDEA: Specialization of `Fn` traits


#1

In theory there could be the following implementation:


impl<Input,Output,F> FnMut<Input> for F
where
    F: FnOnce(Input) -> Output + Clone
{
    extern "rust-call" fn call_mut(&mut self, args: Input) -> Output {
        (self.clone())(args)
    }
}
impl<Input,Output,F> Fn<Input> for F
where
    F: FnOnce(Input) -> Output + Clone
{
    extern "rust-call" fn call(&self, args: Input) -> Output {
        (self.clone())(args)
    }
}

The problem here, is of cause this inevidablely results in conflict implementations. Can specialization solve this problem and then we can put the above in std?


#2

A hidden clone() in a function call seems against Rust’s philosophy, but you can easily wrap this yourself: move |args...| (my_fn.clone())(args...)


#3

Or you could change the fn names in the initial proposal to include the clone semantics in the name, thereby making that aspect not hidden: fn call_cloned_mut() and fn call_cloned().


#4

Right. Maybe some library functions like as_fn?

fn as_fn<Input,Output>(f: impl FnOnce<Input,Output=Output>) + Clone) 
    -> impl Fn<Input,Output=Output> {
    ...
}

(requires unstable rust-call calling convention to make it generic)


#5

This would not be good enough, as you will have to call those functions manually, not by the function call grammar.


#6

I think this is in the same category as the long-desired impl<T:Copy> Clone for T – not something possible right now, with further discussion waiting on the traits refactoring work (chalk, etc).