Blocks

Meta: blocks are doing a lot of work in Dang — they're the iteration protocol, the Ruby-ish DSL hook, the lambda-equivalent, and the body of conditionals/loops. Worth a paragraph naming them explicitly as "the lambda of Dang."

What a block is

Block arguments to functions

# zero-arg block returning Int! (parens omitted)
pub twice(&body: Int!): Int! {
  body + body
}

# block taking args: &name(params): Ret
pub myFun(&block(x: Int!): String!): String! {
  block(42)
}
twice { 21 }                  # ⇒ 42, body takes no args
twice { let n = 21, n }       # multi-statement (separate with newline or `,`)
list.map { x => x * 2 }       # built-in
withArg("Number: ") { x => toJSON(x) }   # args then block
list.each { item, index => ... }

Optional parameters

[1, 2, 3].map { "whee" }        # param ignored ⇒ ["whee", "whee", "whee"]
numbers.filter { true }         # param ignored ⇒ all
numbers.filter { false }        # ⇒ []

Scoping

Control-flow handoff

Meta: the cute Ruby-esque part. return inside a .map/.each block unwinds the enclosing function, not just the block.

When to use a block vs. a function reference

Common methods that take blocks