Balanced Ternary (tbb)
Nitpick's tbb types are balanced binary integers carrying an out-of-band
ERR sentinel. A pick over a tbb selector dispatches on the finite
trit domain {-1, 0, 1} plus the ERR case.
The trit domain
A single trit has exactly three ordinary values and one error value, so a
pick that covers -1, 0, and 1 is exhaustive without a (*) arm for the
ordinary cases — but the ERR case is still routed (see below).
func:failsafe = int32(tbb32:err) { exit 1i32; };
func:main = int32() {
tbb32:t = 1tbb32;
pick (t) {
(-1tbb32) { exit 0i32; },
(0tbb32) { exit 1i32; },
(1tbb32) { exit 2i32; },
(*) { exit 9i32; }
}
exit 0i32;
};
The ERR sentinel
Every tbb width reserves a bit pattern that means "this value is the result of
a failed computation". When the selector evaluates to ERR:
- a
(*)arm, if present, runs; - otherwise the program routes to
func:failsafe.
The codegen widens narrower tbb selectors to the comparison width while
preserving the ERR sentinel, so an ERR tbb8 stays ERR when matched against
tbb32 arms rather than aliasing onto an ordinary value.
Sticky ERR
ERR is sticky: any arithmetic that consumes an ERR tbb produces ERR. So if the
selector expression itself contains a failed tbb operation, the whole pick
sees ERR and takes the failsafe/* path — you never silently match an ordinary
arm on a poisoned value.
(K test 033 and the v0.37.4 tbb/trit tests model the finite domain and the
ERR sentinel; balanced-binary arithmetic with sticky ERR is documented in
SEMANTIC_GAPS.md.)