Have you ever used an iterator adapter in Rust? Called a method on Option? Spawned a thread? You’ve almost certainly used a closure. The design in Rust may seem a little complicated, but it slides right into Rust’s normal ownership model so let’s reinvent it from scratch.
The new design was introduced in RFC 114, moving Rust to a model for closures similar to C++11’s. The design builds on Rust’s standard trait system to allow for allocation-less statically-dispatched closures, but also giving the choice to opt-in to type-erasure and dynamic dispatch and the benefits that brings. It incorporates elements of inference that “just work” by ensuring that ownership works out.
Steve Klabnik has written some docs on Rust’s closures for the official documentation. I’ve explicitly avoided reading it so far because I’ve always wanted to write this, and I think it’s better to give a totally independent explanation while I have the chance. If something is confusing here, maybe they help clarify.
In a sentence: a closure is a function that can directly use variables from the scope in which it is defined. This is often described as the closure closing over or capturing variables (the captures). Collectively, the variables are called the environment.