Continuing the discussion from Reusing mutable closure arguments:
Now I am passing closures by mutable reference, I have a function that is required to return a closure, which seems to work quite nicely with boxing:
pub fn gt<A : PartialOrd>(a : &A, b : &A) -> bool {
*a > *b
}
pub fn test2<R, A>(r : &mut R, a : &A, b : &A)
where R : FnMut(&A, &A) -> bool {
println!("{}", r(a, b));
}
pub fn complement_of_converse<'a, R, A>(r : &'a mut R) ->
Box<FnMut(&A, &A) -> bool + 'a>
where R : FnMut(&A, &A) -> bool {
Box::new(move |a, b| !r(b, a))
}
pub fn test3<R, A>(r : &mut R, a : &A, b : &A)
where R : FnMut(&A, &A) -> bool {
test2(&mut &mut *complement_of_converse(r), a, b);
}
test3(&mut gt, &3, &4);
test3(&mut gt, &4, &4);
My question is, why when I unbox the closure do I need to pass a mutable reference to a mutable reference to the closure? By my thinking the object in the Box has type "R : FnMut(&A, &A) -> bool" and the type "test2" is expecting is "&mut R", I would expect it to be "test2(&mut *complement_of_converse(r), a, b);". Obviously one of my assumptions is wrong, the question is, which one?
Another question is why doesn't the boxed closure implement FnMut so I can pass it directly? My understanding would be the functions take an argument that implements a trait, rather than a trait object. If the compiler is able to pass the closure to 'test2' then it must be able to statically determine the type of the closure, and if it can do that why does the closure need to be boxed to return it? Is the compiler actually able to implement this whole program as a monomorphised static program?