Closures

In Rust, we have a separate syntax for closures. In Perl, we re-use sub. For example, we can create an anonymous subroutine and call it like so.

my $greet2 = sub($name) {say "Hello, $name!"};

$greet2->("Tim");

The subroutine itself doesn't have a name. $greet2 is an ordinary Perl scalar that holds a coderef. The same thing in Rust looks like this.

fn main() {
let greet2 = |name| {println!("Hello, {}!", name)};

greet2("Tim");
}

The name of the variable goes between those two pipes. You can think of both pipes as the lambda in lambda calculus (so |name| is like λ name). This is similar to the Ruby syntax, except in Rust the pipes go on the outside of the block and in Ruby they go on the inside. Ironically, this probably means that you are going to type it wrong a lot if you are familiar with Ruby, but you will learn it quickly and easily if you have never seen anything like it before. Seems kind of unfair!

We can also access variables in the outer scope. In Perl, an alternative way to write the above is

my $name = "Tim";
my $greet3 = sub {say "Hello, $name!"};
$greet3->();

Here the anonymous subroutine takes no argument. It is accessing the $name variable in the outer scope. In Rust, we have just the two pipes with nothing between.

fn main() {
let name = "Tim";
let greet3 = || {println!("Hello, {}!", name)};
greet3();
}

All of the above print

Hello, Tim!