DriftScript
Documentation

Rationale

Why JavaScript is a backend

The single most important technical rule in the language, and what it protects.

Why is JavaScript a backend rather than the specification?

Because everything this language guarantees is something JavaScript does not, and a language whose semantics were defined by its first code generator could never have guaranteed any of it.

The list is the argument

Checked integers, option types instead of undefined, deterministic random streams, controlled time sources, effect checking, restricted host access, typed handles, schema-driven persistence, task cancellation, and stable identities across a reload. Not one of those follows from the target, and several contradict it.

// Integers say what they do when a result does not fit. There is no undefined behaviour.
//
// A plain `+` fails rather than producing a value outside the type. `+%` wraps and `+|` saturates,
// and choosing is the point: a health bar saturates, a hash wraps, a count should fail.

fn health(current: u8, healed: u8) -> u8 {
    return current +| healed
}

fn hashStep(accumulator: u32, value: u32) -> u32 {
    return accumulator *% value
}

// Units are erased. `30m` is the number 30; `250ms` is 0.25, because seconds are the base unit.
fn reach() -> f32 {
    return 30m
}

fn beat() -> f32 {
    return 250ms
}
A u8 that saturates, compiled to JavaScript, which has neither u8 nor saturation.

What keeps it honest

A typed intermediate representation is emitted before any backend runs, which is what makes a second backend a backend rather than a rewrite. It is also the thing that would quietly stop being true if the emitter were allowed to shortcut.

What it costs

Generated code is not the code you wrote, so a stack trace needs a source map to mean anything, and the compiler has to carry the whole IR rather than printing as it parses. It also means some JavaScript idioms have no spelling here, and never will.