Closed PreviewCompiler source opens July 1, 2026. Playground and binary available today.Join Discord →
MetaScript
Expressions

Expressions

Operators, control flow, pattern matching, and error handling

Expressions produce values. MetaScript's expression forms follow TypeScript closely with two notable extensions: match (pattern matching) and Result<T, E> (error handling without exceptions).

Operators

// Arithmetic
+ - * / % **

// Comparison
== != < > <= >=
=== !== // Strict equality

// Logical
&& || !

// Bitwise
& | ^ ~ << >> >>>

// Assignment
= += -= *= /= %= **=
&= |= ^= <<= >>= >>>=

// Nullish
?? // Nullish coalescing
?. // Optional chaining

Control flow

if / else

if (condition) {
    // ...
} else if (other) {
    // ...
} else {
    // ...
}

Ternary

const result = condition ? "yes" : "no";

switch

switch (value) {
    case 1:
        // ...
        break;
    case 2:
    case 3:
        // ...
        break;
    default:
        // ...
}

match (pattern matching)

MetaScript extension. Destructures the value and selects the matching arm. Exhaustive — the compiler errors if a case is missed.

match (result) {
    { ok: true, value } => console.log(value),
    { ok: false, error } => console.error(error),
}

Works with discriminated unions, tuples, and nested shapes — see Types for the type-level story.

Loops

// C-style
for (let i = 0; i < 10; i++) {
    // ...
}

// Iterable
for (const item of items) {
    // ...
}

// Object keys
for (const key in object) {
    // ...
}

// while
while (condition) {
    // ...
}

// do...while
do {
    // ...
} while (condition);

Error handling

MetaScript supports two styles, each with its place:

Exceptions (for unexpected failures)

try {
    riskyOperation();
} catch (error) {
    console.error(error);
} finally {
    cleanup();
}

throw new Error("Something went wrong");

Result<T, E> (for expected failures)

Prefer Result when failure is a normal outcome the caller should handle — parsing, validation, I/O. Propagate with the try prefix operator and branch with match or a direct .ok check.

function parseNumber(s: string): Result<number, string> {
    const n = Number(s);
    if (Number.isNaN(n)) return Result.err("not a number");
    return Result.ok(n);
}

// Propagation
function sumTwo(a: string, b: string): Result<number, string> {
    const x = try parseNumber(a);
    const y = try parseNumber(b);
    return Result.ok(x + y);
}

// Pattern matching
match (sumTwo("3", "4")) {
    { ok: true, value } => console.log(value),
    { ok: false, error } => console.error(error),
}

See also

  • Declarations — variables, functions, classes
  • Types — including Result<T, E> and discriminated unions
  • Modules — imports and exports