Status
Accepted
Context
Slug intentionally keeps the primitive type set small and prioritizes values that are easy to reason about, portable, and predictable across platforms and runtimes.
Using IEEE-754 binary floating point as the sole numeric type introduces user-visible surprises for common decimal arithmetic (money, percentages, measurements) and can result in platform-dependent edge cases.
Slug’s design goals favor:
- explicit semantics over implicit coercions
- deterministic behavior across interpreters and virtual machines
- predictable formatting and serialization
- clear failure modes rather than silent corruption or “weird values”
To support these goals, Slug requires a decimal-based numeric representation with well-defined rounding, overflow, and conversion behavior.
Decision
Slug’s number type is DEC64.
Representation
- A
numberrepresents a decimal value of the form:
coefficient × 10^exponent
-
The coefficient and exponent are bounded and finite.
-
The runtime maintains a canonical (normalized) representation where possible, such that equivalent numeric values compare equal and format consistently.
-
Representation details (bit layout, packing strategy) are explicitly not part of the language contract and may vary between runtimes, provided observable semantics remain consistent.
Numeric operation semantics
- The arithmetic operators
+,-, and*operate in decimal space and must be deterministic. -
/performs decimal division with defined defaults:- Default precision: 16 significant digits
- Default rounding mode: half-even (banker’s rounding)
- The standard library provides explicit alternatives for callers that require different precision or rounding behavior.
Error model (no NaN in userland)
- Slug user code does not observe NaN or Infinity as normal values.
-
Invalid numeric operations raise a RuntimeError, including:
- division by zero
- overflow or underflow beyond the representable DEC64 range
- invalid numeric conversions
- bitwise operations applied to non-integer values
- Runtimes may use internal sentinel values to implement numeric operations, but these must never be exposed directly to user code.
Integer-ness and bitwise operations
- A
numberis considered an integer if it has no fractional component in canonical form. - Bitwise operators (
&,|,^,~,<<,>>) are only valid on integer values. - Applying bitwise operations to non-integers raises a RuntimeError.
Conversions and interop
-
All numeric conversions are explicit and checked:
toInt()succeeds only if the value is an exact integer within range.toFloat()is permitted but explicitly lossy.
-
Serialization and parsing:
- The standard library must support stable decimal string formatting.
- Canonical formatting must round-trip:
parse(format(x)) == x. - JSON support may encode numbers either as numeric values or strings; string encoding is recommended when exact round-trip fidelity is required (e.g. money).
Consequences
Positive
- Predictable decimal arithmetic aligned with human expectations.
- Deterministic behavior across runtimes and platforms.
- A smaller, simpler numeric surface area with fewer coercion rules.
- Clear, explicit failure modes instead of silent numeric corruption.
Negative
- Numeric performance may be lower than hardware-accelerated binary floating point.
- Some domains (e.g. scientific simulation, graphics, machine learning) may find DEC64 less suitable.
- The language must clearly specify rounding, precision, and overflow behavior to avoid ambiguity.
Neutral
- Slug prioritizes correctness, readability, and predictability over maximum numeric throughput.
- Alternate numeric representations (e.g. binary floats, big decimals, rationals) remain possible as library types, not language primitives.