IDEA: Specialization of `Fn` traits

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?

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 Likes

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().

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)

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

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

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.