# Blocks, yield, and lambdas

> Pass behavior using literal blocks, typed block parameters, lambdas, and symbol shorthand.

Canonical: https://alice-lang.org/documentation/language/blocks/

[Documentation index](https://alice-lang.org/documentation/llms.txt) · [Complete book](https://alice-lang.org/llms-full.txt)

## Pass a block

A block is behavior supplied to a call. Brace form uses `{ |parameters| body }`; multiline form uses `do |parameters| ... end`.

```alice
def apply(x : Int32, &f : Int32 -> Int32) : Int32
  yield x
end
puts apply(3) { |n| n * 10 }
square = ->(n : Int32) { n * n }
puts square.call(7)
puts ["alice", "rabbit"].map(&:upcase).join(", ")
```

Expected output:

```text
30
49
ALICE, RABBIT
```

[Edit and run in the Alice playground](https://playground.alice-lang.org/#code=u.ZGVmIGFwcGx5KHggOiBJbnQzMiwgJmYgOiBJbnQzMiAtPiBJbnQzMikgOiBJbnQzMgogIHlpZWxkIHgKZW5kCnB1dHMgYXBwbHkoMykgeyB8bnwgbiAqIDEwIH0Kc3F1YXJlID0gLT4obiA6IEludDMyKSB7IG4gKiBuIH0KcHV0cyBzcXVhcmUuY2FsbCg3KQpwdXRzIFsiYWxpY2UiLCAicmFiYml0Il0ubWFwKCY6dXBjYXNlKS5qb2luKCIsICIp)

`apply` declares a block taking an `Int32` and returning an `Int32`. `yield x` invokes the caller's block. A block with no result can use a signature such as `Int32 ->`.

Alice also supports inferring an implicit block parameter from `yield` in supported Ruby-style DSL definitions. An explicit signature gives a reusable API a clear contract.

## Iterate or transform

```alice
[1, 2, 3].each do |n|
  puts n
end
result = [1, 2, 3].map { |n| n * 10 }
```

`each` is for effects; `map` creates transformed values. Use `select` to keep matching values and a sink such as `sum` to reduce them. Literal iterator blocks can be inlined and fused by the compiler, so you do not need to rewrite every pipeline as a manual loop.

## First-class lambdas

`->(x : Int32) { x * x }` creates a callable value. Invoke it with `.call(7)` or `.(7)`. The `lambda { |x : Int32| ... }` and `proc { |x : Int32| ... }` forms are also supported.

Typed lambdas adapt to .NET delegates, which is useful for events, LINQ, and framework callbacks. Keep parameter and return types compatible with the destination delegate.

## Symbol-to-block shorthand

`names.map(&:upcase)` is shorthand for a block that calls `upcase` on each element. Use a full block when there are arguments, extra checks, or multiple operations.

## Captures

A block can read values from its surrounding scope. A mutable capture can add state and allocation, depending on how the block is lowered. Capture-free lambdas can emit static delegates; literal iterator blocks often emit no delegate at all.

When a block runs concurrently, captured mutation is subject to [race checks](https://alice-lang.org/documentation/concurrency/race-safety.md). A sequential `each` body and a `Par.For` body do not have the same permission to change shared state.

For receiver-based blocks such as `instance_eval`, see [dynamic features and DSLs](https://alice-lang.org/documentation/language/dynamic.md).

## Continue reading

- Previous: [Methods and calls](https://alice-lang.org/documentation/language/methods.md)
- Next: [Classes and objects](https://alice-lang.org/documentation/language/classes.md)
