Enums — Fieldless Variants

  type Direction = enum {
    North,
    South,
    East,
    West,
};

var d = Direction.North;

-- enums are always Copy
case d {
    .North => debug.print("going north\n"),
    .South => debug.print("going south\n"),
    .East  => debug.print("going east\n"),
    .West  => debug.print("going west\n"),
}
  

Unions — Tagged Variants With Data

  type Shape = union {
    Circle   { radius: f32 },
    Rectangle { width: f32, height: f32 },
    Triangle  { base: f32, height: f32 },
    Point,                                -- unit variant, no data
};

fn area(shape: Shape): f32 {
    return case shape {
        .Circle { radius }        => 3.14159 * radius * radius,
        .Rectangle { width, height } => width * height,
        .Triangle { base, height }   => 0.5 * base * height,
        .Point                    => 0.0,
    };
}

var s = Shape.Circle { .radius = 5.0 };
debug.print("area: {}\n", .{area(s)});
  

Optionals — ?T

An optional is either a value or nothing:

  var x: ?i32 = 5;
var y: ?i32 = .None;

-- four ways to handle optionals:

-- orelse: provide a default
var n = x orelse 0;
var n = x orelse return error.Missing;

-- ? operator: propagate None upward
var n = x?;

-- if unwrap
if x |val| {
    debug.print("got {}\n", .{val});
}

-- case
case x {
    .Some { value } => debug.print("got {}\n", .{value}),
    .None           => debug.print("nothing\n"),
}
  

Finding something in a list:

  fn findFirst(items: []const i32, target: i32): ?usize {
    for item, i in items {
        if item.* = target { return i; }
    }
    return .None;
}

if findFirst(&.{1, 2, 3, 4, 5}, 3) |idx| {
    debug.print("found at index {}\n", .{idx});
}
  

Pattern Guards

  case shape {
    .Circle { radius } if radius > 10.0 => debug.print("large circle\n"),
    .Circle { radius }                  => debug.print("small circle\n"),
    _                                   => debug.print("other shape\n"),
}