Mica’s math unit is the first standard-library user of the
generics machinery, and its design fits in one
sentence: everything the language can say is written in Mica, and
everything C owns stays C’s, by name.
The example is
examples/MathUnit.
Build and run it:
make -C examples/MathUnit runOne source, every width
Min, Max, Clamp, Abs and Sign are each a short generic function
over a constrained type parameter, monomorphized per concrete type:
w := Clamp(12, 0, 10); { int64: 10 }
tiny := Clamp((0.25 as float32), (0.0 as float32), (1.0 as float32));The float32 answer stays float32 — no widening to double and back, which
is the fidelity a generic road exists to buy. Each constraint is exactly
what the body does: comparison for the order family, comparison and
negation for Abs, the numeric literals beside both for Sign.
The integer verbs are Gcd (Euclid), Lcm through it, and PowInt by
binary squaring — integral types only, because an integer power of an
integer is an integer fact.
Constants are declarations
Pi, E, Tau and the machine epsilons are spelled as what they are —
Tau is literally the expression 2.0 * Pi — so Tau / Pi = 2.000000
is arithmetic, not folklore.
Classification through arithmetic
IsNan and IsInf read IEEE facts with no bit tricks and no C call: a
value that disagrees with itself is the not-a-number, and a nonzero value
that survives exact halving unchanged is an infinity.
while not IsInf(inf) do
inf := inf * inf * 16.0;
nan := inf - inf;Equality is exact; tolerance is spelled
A float comparison computes precisely what the runtime instruction
computes — at compile time and at run time, the bit-exact doctrine — so
0.1 + 0.2 = 0.3 is honestly False, and the place a tolerance lives is
a verb that names one:
ApproxEqual(f, 0.3, Epsilon64 * 4.0) { True — at a tolerance you chose }The libm seam
The transcendentals are deliberately absent from math: C owns libm, and
the well-known names — Sqrt, Sin, Exp, Tanh — are reserved against
user declaration so imp Sqrt : cstd can never be shadowed. The unit’s
own import block states the split of labor:
imp
Min, Max, Clamp, Abs, Sign, Gcd, Lcm, PowInt, ApproxEqual, IsNan, IsInf, Pi, Tau, Epsilon64 : math;
Sqrt : cstd;One meaning per word, and qualification makes the
origin sayable at the call site too: cstd.Sqrt(2.0).
What this does not do
- No overloading. One name, one declaration —
Minthe scalar pair lives here; the reductionMinimumlives with the reductions, Julia’s own split. - No integral mean, no silent conversions. Where a formula needs a fractional answer from integers, you spell the conversion.
- No epsilon hidden in
=. Equality is exact everywhere; tolerance isApproxEqual’s third argument, visible at every call.
Try it
Change the tolerance to Epsilon64 alone and watch ApproxEqual answer
False — the gap between 0.1 + 0.2 and 0.3 is real, measurable, and
exactly two ulps wide.
Next
The unit’s other half — the verbs over many elements — is the reductions family, where determinism becomes a promise about parallelism.