Return closure by value vs. by ref

Now we can return a closure by value :sunglasses:. I am wondering, in what scenario rustaceans may want to return a closure by value and in what scenario by ref.? Thank you

@bogdan.kulbida Welcome to Rust and the user forums!

Always try and return by value when you can. This way you can avoid dynamic dispatch, which can be slow because it prevents many optimizations based on inlining.

2 Likes

Much appreciated your quick reply!

Ideally you return closures by value, but since the type of a closure cannot be named / expressed, it requires -> impl Trait notation, e.g., -> impl Fn(Args) -> RetType:

fn add (x: i32) -> impl Fn(i32) -> i32
{
    move |y: i32| -> i32 {
        x + y
    }
}

fn main ()
{
    dbg!(
        add (42) (27)
    );
}

and sadly that notation does not work yet with traits, meaning that in stable Rust you cannot do something like

trait CurryAdd
where
    Self : ::core::ops::Add<Self, Output = Self>,
    Self : Copy + 'static, // simpler example
{
    fn add (x: Self) -> impl Fn(Self) -> Self
    {
        move |y: Self| -> Self {
            x + y
        }
    }
}
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
 --> src/main.rs:6:25
  |
6 |     fn add (x: Self) -> impl Fn(Self) -> Self

If you want such ergonomics in stable Rust, you need to use a trait object, which needs to be behind a reference, e.g., a Box:

#![deny(bare_trait_objects)]

trait CurryAdd
where
    Self : ::core::ops::Add<Self, Output = Self>,
    Self : Copy + 'static, // simpler example
{
    fn add (x: Self) -> Box<dyn Fn(Self) -> Self>
    {
        Box::new(move |y: Self| -> Self {
            x + y
        })
    }
}
5 Likes