`when` handles conditionals. Three forms: simple, bare (all matches), first (switch-style). **Simple form:** ```mlld when @isProd => show "Production mode" when @score > 90 => show "Excellent!" ``` **Bare form** (evaluates all matching conditions): ```mlld when [ @score > 90 => show "Excellent!" @hasBonus => show "Bonus earned!" none => show "No matches" >> runs only if nothing matched ] ``` **First form** (stops at first match, like switch): ```mlld when first [ @role == "admin" => show "Admin panel" @role == "user" => show "User dashboard" * => show "Guest view" >> wildcard catches all ] ``` **Value-returning when** (in exe): ```mlld exe @classify(score) = when first [ @score >= 90 => "A" @score >= 80 => "B" * => "F" ] var @grade = @classify(85) >> "B" ``` **Block actions** (side effects + return): ```mlld var @result = when first [ @needsProcessing => [ show "Processing..." let @processed = @transform(@data) => @processed ] * => @data ] ``` **Local variables in when:** ```mlld when @mode: [ let @prefix = "Status:" "active" => show "@prefix Active" "pending" => show "@prefix Pending" * => show "@prefix Unknown" ] ``` **Augmented assignment:** ```mlld exe @collect() = when [ let @items = [] @items += "a" @items += "b" * => @items >> ["a", "b"] ] ``` `+=` works with arrays (concat), strings (append), objects (merge). **Operators in conditions:** - Comparison: `<`, `>`, `<=`, `>=`, `==`, `!=` - Logical: `&&`, `||`, `!` - Parentheses: `(@a || @b) && @c` ```mlld when first [ @role == "admin" || @role == "mod" => show "Privileged" @active && @verified => show "Active user" !@banned => show "Allowed" * => show "Blocked" ] ``` `for` iterates over collections. Arrow form for single actions, block form for multiple. **Arrow form:** ```mlld for @item in @items => show `Processing @item` for @n in [1,2,3] => log @n ``` **Collection form** (returns results): ```mlld var @doubled = for @x in [1,2,3] => @x * 2 >> [2, 4, 6] var @names = for @user in @users => @user.name ``` **Block form:** ```mlld for @item in @items [ let @processed = @transform(@item) show `Done: @processed` ] >> Collection with block var @results = for @item in @items [ let @step1 = @validate(@item) let @step2 = @transform(@step1) => @step2 ] ``` **For with inline filter:** ```mlld var @valid = for @x in @items when @x != null => @x var @admins = for @u in @users when @u.role == "admin" => @u.name ``` **Skip keyword** (drop items from results): ```mlld var @filtered = for @x in @items => when [ @x.valid => @x none => skip >> omit this item from results ] >> Equivalent to inline filter, but allows complex logic var @processed = for @item in @data => when first [ @item.type == "a" => @transformA(@item) @item.type == "b" => @transformB(@item) * => skip >> unknown types dropped ] ``` **Object iteration:** ```mlld var @cfg = {"host": "localhost", "port": 3000} for @v in @cfg => show `@v.mx.key: @v` >> Output: host: localhost, port: 3000 ``` **Nested for:** ```mlld for @x in ["A","B"] => for @y in [1,2] => show `@x-@y` >> Output: A-1, A-2, B-1, B-2 ``` **Batch pipelines** (process collected results): ```mlld var @total = for @n in [1,2,3,4] => @n => | @sum var @sorted = for @item in @items => @process(@item) => | @sortBy("priority") ``` Run iterations concurrently with `for parallel`. ```mlld >> Default concurrency (MLLD_PARALLEL_LIMIT, default 4) for parallel @x in @items => show @x >> Custom concurrency cap for parallel(3) @task in @tasks => @runTask(@task) >> With pacing (delay between starts) for parallel(2, 1s) @x in @items => @process(@x) ``` **Parallel blocks:** ```mlld for parallel(3) @task in @tasks [ let @result = @runTask(@task) show `Done: @task.id` ] ``` **Error handling:** - Errors accumulate in `@mx.errors` - Failed iterations add error markers to results - Outer-scope writes blocked (use block-scoped `let` only) ```mlld exe @process(tasks) = [ let @results = for parallel @t in @tasks => @run(@t) => when [ @mx.errors.length == 0 => @results * => @repair(@results, @mx.errors) ] ] ``` `foreach` applies a function to each element, returning transformed array. ```mlld var @names = ["alice", "bob", "charlie"] exe @greet(name) = `Hi @name!` var @greetings = foreach @greet(@names) >> ["Hi alice!", "Hi bob!", "Hi charlie!"] ``` **In exe:** ```mlld exe @wrapAll(items) = foreach @wrap(@items) show @wrapAll(["a", "b"]) >> ["[a]", "[b]"] ``` **With options:** ```mlld show foreach @greet(@names) with { separator: " | " } >> "Hi alice! | Hi bob! | Hi charlie!" ``` Bounded iteration with `while`. ```mlld exe @countdown(n) = when [ @n <= 0 => done "finished" * => continue (@n - 1) ] var @result = 5 | while(10) @countdown ``` **Control keywords:** - `done @value` - Terminate, return value - `done` - Terminate, return current state - `continue @value` - Next iteration with new state - `continue` - Next iteration with current state **While context** (`@mx.while`): - `iteration` - Current iteration (1-based) - `limit` - Configured cap - `active` - true when inside while **With pacing:** ```mlld var @result = @initial | while(100, 1s) @processor >> 1s between iterations ``` mlld has no `return` or `exit`. Model outcomes with `when` and flags. ```mlld >> Instead of early return, use conditional flow var @check = @validate(@input) when [ @check.valid => @process(@input) !@check.valid => show `Error: @check.message` ] ```