records

Records: literals, field shorthand, functional update, and record patterns.

examples/data/records.dawn

# Records: literals, field shorthand, functional update, and record patterns.
#
# Run: dawn run examples/data/records.dawn

type Point = { x: Float, y: Float }
type Line = { a: Point, b: Point }

fn dx(l: Line) -> Float = l.b.x - l.a.x

fn describe(p: Point) -> String =
  match p {
    Point { x: 0.0, y: 0.0 } -> "the origin"
    Point { x, y: 0.0 } -> "on the x axis at $x"
    Point { x, y } -> "($x, $y)"
  }

pub fn main() -> Unit !io = {
  let p = Point { x: 3.0, y: 4.0 }
  println("p = ${describe(p)}")
  println("p.x = ${p.x}")

  # functional update: a new record, the original is untouched
  let q = Point { ..p, y: 0.0 }
  println("q = ${describe(q)}")

  # shorthand: { x, y } picks up the bindings named x and y
  let x = 0.0
  let y = 0.0
  println("o = ${describe(Point { x, y })}")

  let l = Line { a: Point { x: 1.0, y: 1.0 }, b: p }
  println("dx = ${dx(l)}")
  println("equal: ${q == Point { x: 3.0, y: 0.0 }}")
}

test "functional update leaves the original alone" {
  let p = Point { x: 3.0, y: 4.0 }
  let q = Point { ..p, y: 0.0 }
  assert q == Point { x: 3.0, y: 0.0 }
  assert p.y == 4.0
}

test "record patterns match on the fields they name" {
  assert describe(Point { x: 0.0, y: 0.0 }) == "the origin"
  assert describe(Point { x: 5.0, y: 0.0 }) == "on the x axis at 5.0"
  assert describe(Point { x: 1.0, y: 2.0 }) == "(1.0, 2.0)"
}