10. Numeric model: separate int and float, / is true division, checked overflow
- Status: Accepted
- Date: 2026-09-02
Context
Number handling is one of the highest-leverage decisions in a dynamic language.
Choices: one number type (float64, like JavaScript/Lua 5.1) or two (int + float);
what / does; and what happens on integer overflow.
Decision
- Two numeric types.
intis a signed 64-bit integer.floatis an IEEE-754 double. A literal with no.and no exponent is anint; otherwise afloat. - Arithmetic promotes.
int op intstaysint(except/); if either operand isfloat, the other is converted tofloatand the result isfloat. /always produces afloat.7 / 2is3.5.10 / 2is5.0. There is one division operator and it means mathematical division. Floor division is not in Milestone 1; if it proves necessary it gets its own operator and ADR.- Integer overflow is a runtime error (
E0306), not silent two's-complement wraparound. Allintarithmetic uses checked operations internally. %is the remainder with the sign of the dividend;x % 0isE0305.- Equality across types:
1 == 1.0istrue(compared by mathematical value). Ordering likewise.
Consequences
intandfloatare visibly different (type(3)vstype(3.0),str(3)="3"vsstr(3.0)="3.0"), which matches user expectation for "is this a whole number"./never surprises a beginner with1/2 == 0. The cost is thata / bon two ints you wanted floored needsint(a / b)(or a future//).- Overflow-as-error trades raw speed and C-like wraparound for predictability. A
program that overflows
i64is almost always buggy; failing loudly is right for a scripting language. Bignum integers are a possible future ADR. - The interpreter's arithmetic path has a 2×2 type match plus checked ops — a little verbose, fully contained in one module.
Alternatives considered
- Single float64 number type. Simplest implementation, but
type()can't distinguish whole numbers, large integers lose precision silently past 2^53, and array indices/loop counters get awkward. /= floor when both ints (Python 2, C). The1/2 == 0footgun; Python itself abandoned it.- Wrapping overflow. Fast and predictable if you know it happens; a silent correctness trap if you don't. Wrong default for scripting.
- Arbitrary-precision
intby default. No overflow at all, but a performance and implementation cost that M1 does not need; leavesi64semantics to reintroduce later. Deferred, not rejected.