
## Functions

Functions use `def`. Parameter types are required. Return type annotations are optional.

```vary
def add(a: Int, b: Int) -> Int {
    return a + b
}

def greet(name: Str, greeting: Str = "Hello") -> None {
    print(f"{greeting}, {name}!")
}

greet("Alice")
greet("Bob", greeting="Hi")   # named argument
```

The `pure` modifier marks a function as side-effect-free. Pure functions can only call other pure functions:

```vary
pure def double(x: Int) -> Int {
    return x * 2
}
```

## Lambdas

Anonymous functions with 0, 1, or 2 parameters:

```vary
let double = lambda x: Int: x * 2
let add = lambda a: Int, b: Int: a + b
print(double(21))       # 42
```

Lambdas capture variables from the enclosing scope:

```vary
def make_adder(n: Int) -> (Int) -> Int {
    return lambda x: Int: x + n
}

let add5 = make_adder(5)
print(add5(10))         # 15
```

## Operators

### Arithmetic

| **Operator** | **Description** | **Example** |
|----------|-------------|---------|
| `+` | Addition or string concatenation | `3 + 4` / `"a" + "b"` |
| `-` | Subtraction | `10 - 3` |
| `*` | Multiplication or string repetition | `6 * 7` / `"ha" * 3` |
| `/` | Division (float result) | `10 / 3` |
| `//` | Integer division (truncates) | `10 // 3` = `3` |
| `%` | Modulo | `10 % 3` = `1` |
| `**` | Power | `2 ** 10` = `1024` |

### Comparison

`==`, `!=`, `<`, `>`, `<=`, `>=` work on numbers, strings, and data types.

### Containment

| **Operator** | **Description** | **Example** |
|----------|-------------|---------|
| `in` | Membership test | `3 in [1, 2, 3]` |
| `not in` | Negated membership test | `"z" not in "hello"` |

Works on `List`, `Set`, `Dict` (tests keys), and `Str` (substring test).

### Logical

`and`, `or`, `not`. Short-circuit evaluation.

### Assignment

`+=`, `-=`, `*=`, `/=`, `|=` (set union in place).
