Mojo Closures
Before this release, Mojo has had several flavors of closures:
- Legacy
capturing[_]closures —@parameterfunctions passed only as compile-time type parameters, with implicit captures (and@__copy_captureto opt into copy semantics). - Escaping closures —
escapingfunctions emitted as heap-allocated struct instances and passed as runtime values. - Unified closures — declared with the
unifiedkeyword, with explicit capture lists (e.g.unified {var x, mut y}), and passed as both a type parameter and a runtime value.
To ease usage of closures and simplify the API the team is collapsing these variants into a single representation.
In the latest nightly, only unified closures exist and they are the default. There is no unified keyword to distinguish them anymore.
More detailed documentation is coming and we are actively working on bug fixes.
Before this change, legacy closures were expressed in the following way:
@always_inline
@parameter
def init_value[width: Int]() capturing -> SIMD[DType.float32, width]:
return 0.0
@always_inline
@__copy_capture(output, scale)
@parameter
def write_result[
width: Int
](idx: Int, val: SIMD[DType.float32, width]) capturing:
output.unsafe_ptr().store(idx, val * scale)
compute_grid[width, init_value, write_result](shape)
Now, closures will look a little different. The same code above is now expressed:
def init_value[width: Int]() -> SIMD[DType.float32, width]:
return 0.0
def write_result[
width: Int
](idx: Int, val: SIMD[DType.float32, width]) {
var output, var scale
}:
output.unsafe_ptr().store(idx, val * scale)
compute_grid[width](init_value, write_result, shape)
Notice how the closures move from the type parameter list ([...]) into the runtime argument list ((...)) — that’s the headline change.
The recipe in one breath:
- Drop
@parameterand@__copy_capture(...)from your closures. - Add an explicit
{ ... }capture list. - Pass closures as value arguments (first positional args), not as explicit type parameters — the compiler infers the types. Keep only the non-closure params (
width,dtype, etc.) explicit.
I am happy to answer any questions and discuss the change. Please file bug reports for any unexpected behavior you may encounter.