Skip to content

If and If Let

Use if when you want to run code only when a condition is true.

let age := 20;
if age >= 18 => {
print("adult");
} else => {
print("minor");
};

Like many Calibre constructs, if is an expression and uses => for its branches.

You can also chain conditions with else if.

let score := 75;
if score >= 90 => print("A")
else if score >= 80 => print("B")
else if score >= 70 => print("C")
else => print("D");

if let combines a condition with pattern matching. It only enters the branch if the value matches the pattern.

This works especially well with enums such as options and results, but it is not limited to them.

if let .Some : value <- some(12) => {
print(value);
};

You can destructure structs directly inside if let.

type Pair := struct { left right : int };
if let {left : l, right : r} <- Pair { left : 4, right : 6 } => {
print(l + r);
};

You can also destructure tuple-like values.

if let (a, b) <- (3, 9) => {
print(a + b);
};

Enum payloads can be matched and destructured too.

type PairEnum := enum { Tuple : <int, int> };
if let .Tuple : (a, 9) <- PairEnum.Tuple : (3, 9) => {
print(a);
} else => {
print(0);
};

Lists can be matched by shape.

if let [4, ..] <- [4, 10, 12] => {
print("starts with 4");
};

String patterns can also be matched.

if let token @ "go:" & payload <- "go:east" => {
print(token);
print(payload);
};

Use if for ordinary boolean conditions, and if let when the question is really “does this value match this shape?”.

Also note that if let supports every pattern supported by match statements and for let and vice-versa.