block - pannous/warp GitHub Wiki

A block is unevaluated code meant to run later: an uncharged expression (vocabulary and timing: charged).

Blocks are written

  • as an uncharged binding: x : a+b
  • as statements in braces: x = {print "hi"; 1+2}
  • with the prefix code or block: xs = [code a+1, code a*2]
  • as the argument of a parameter declared block: unless(c, body:block) := if !c: body!

A block written after a call's arguments is its last argument, so your own functions read like control flow (samples/functions/block_arguments.warp):

repeats(n: int, body: block) := { for i in 1...n { body! } }
repeats 3 { print "Hello" }

A parameter named block is a block too: repeats(n: int, block) := … runs it with block(). An untyped parameter of another name is not one yet (card untyped-block-parameter). The built-in form is 3 times { print "Hi" }.

A block runs with ! (once) or !! (fully, including nested blocks); names inside it resolve where ! is written. Control flow takes blocks: if c {…}, while c {…}, for x in xs {…}, def f {…} run their block when they decide to, see do.

A block used where a value is needed is a type error with the fix (x!, or x = … instead of x : …). A block has no declared parameters; one that uses it is a one-parameter closure (map [1 2 3] {it*it}). Unlike data, a block is meant to run.