lambdas

Function values: lambdas, captures, higher-order functions, effect variables.

examples/basics/lambdas.dawn

# Function values: lambdas, captures, higher-order functions, effect variables.
#
# Run: dawn run examples/basics/lambdas.dawn

fn double(x: Int) -> Int = x * 2

# effect-polymorphic user HOF: pure in, pure out; io in, io out
fn apply_twice(f: fn(Int) -> Int !e, x: Int) -> Int !e = f(f(x))

pub fn main() -> Unit !io = {
  # lambdas and captures
  let offset = 100
  let shift = (x: Int) => x + offset
  println("shift(1) = ${shift(1)}")

  # top-level functions are values
  println("${map([1, 2, 3], double) == [2, 4, 6]}")

  # pipes + higher-order builtins
  range(1, 11)
    |> filter(x => x % 2 == 1)
    |> map(x => x * x)
    |> fold(0, (a, b) => a + b)
    |> total => println("sum of odd squares: $total")

  # effect polymorphism
  println("${apply_twice(n => n + 1, 40)}")
  let noisy = apply_twice(n => {
    println("step $n")
    n * 2
  }, 3)
  println("noisy = $noisy")
}

test "a top-level function is a value like any other" {
  assert map([1, 2, 3], double) == [2, 4, 6]
}

test "the same HOF serves a pure `f`" {
  assert apply_twice(n => n + 1, 40) == 42
  assert apply_twice(double, 3) == 12
}

test "a lambda closes over what it can see" {
  let offset = 100
  let shift = (x: Int) => x + offset
  assert map([1, 2], shift) == [101, 102]
}