Units and Uncertainty
Compile-time unit checking and GUM-based uncertainty propagation in Sounio
Units and Uncertainty
Does Sounio have built-in unit checking? Yes. Physical dimensions are checked at compile time.
How do I propagate measurement uncertainty? Use Knowledge<T> with GUM (Guide to the Expression of Uncertainty in Measurement) propagation.
Dimensional analysis — compile-time unit checking
Sounio checks physical dimensions at the type level. Adding meters to seconds is a compile error, not a runtime bug.
fn main() with IO {
let distance: m = 100.0
let time: s = 9.58
// This compiles: m / s = m/s
let velocity = distance / time
println(velocity) // 10.438413
// This is a COMPILE ERROR:
// let wrong = distance + time
// error[E041]: unit mismatch in arithmetic operation
// left unit: length^1
// right unit: time^1
}
Unit declarations
// Base units
let mass: kg = 75.0
let length: m = 1.80
let time: s = 10.0
// Derived units compose automatically
let velocity: m = length / time // m/s
let acceleration = velocity / time // m/s^2
let force = mass * acceleration // kg·m/s^2 (newtons)
Verified example
The full dimensional-safety example is examples/showcase/type_safe_units.sio. It demonstrates:
- Projectile motion simulation with full dimensional checking
- Kinetic energy: KE = 0.5 × m × v²
- Newton’s second law: F = m × a
- Every operation verified dimensionally
Run it:
./bin/souc run examples/showcase/type_safe_units.sio
Uncertainty propagation — Knowledge<T> and GUM
Knowledge<T> represents a measured value with its standard uncertainty. Uncertainty propagates through calculations following the Guide to the Expression of Uncertainty in Measurement (JCGM 100:2008).
// Measurements with uncertainty
let mass = Measurement { value: 75.0, uncertainty: 0.5 } // 75.0 ± 0.5 kg
let height = Measurement { value: 1.80, uncertainty: 0.01 } // 1.80 ± 0.01 m
// Uncertainty propagates through BMI = m/h²
let bmi = compute_bmi(mass, height)
// Result: 23.148 ± 0.300 kg/m²
// Variance budget: which input dominates?
// Height contributes ~96% of BMI uncertainty
The implementation uses automatic differentiation to compute partial derivatives and combines uncertainties via the law of propagation:
u_c²(y) = Σᵢ (∂f/∂xᵢ)² · u²(xᵢ)
Verified example
The full GUM propagation example is examples/science/uncertainty_propagation.sio. It computes:
- BMI = mass / height²
- BSA (body surface area, Mosteller formula)
- Full variance budget showing which measurements dominate uncertainty
Run it:
./bin/souc run examples/science/uncertainty_propagation.sio
Expected output:
BMI = 23.148 +/- 0.300 kg/m^2
BSA = 1.936 +/- 0.008 m^2
Variance: mass=3.8%, height=96.2%
PBPK with units and uncertainty
The PBPK (physiologically-based pharmacokinetic) library combines both: drug concentrations carry units (mg/L, μmol/L) and uncertainty from measurement and physiological variability.
Example: rapamycin blood concentration with GUM uncertainty propagation through a 14-compartment model — stdlib/darwin_pbpk/.
./bin/souc run examples/darwin_pbpk/simulation_demo.sio
Comparison with other approaches
| System | Unit checking | Uncertainty | Notes |
|---|---|---|---|
| Sounio | Compile-time, dimensional algebra | GUM via Knowledge<T>, first-class | Integrated: units + uncertainty in one type system |
| F# units of measure | Compile-time, erased at runtime | No built-in support | Clean syntax, no runtime overhead |
| Ada/GNAT | Compile-time via dimension types | No built-in support | Strong typing, verbose declarations |
| Numbat | Physical units + conversion | No uncertainty | Calculator/scripting focus |
| Python (Pint + uncertainties) | Runtime checking | Runtime propagation | Flexible but slow; no compile-time safety |
| Julia (Unitful + Measurements) | Runtime checking | Runtime propagation | Composable packages, runtime overhead |
Sounio’s approach: compile-time dimension checking + first-class GUM uncertainty, integrated into the type system and the compiler’s automatic differentiation.
Status and limitations
-
Units: Compile-time checking works. Derived units (
m/s,kg·m/s²) compose correctly. Full coverage verified inexamples/showcase/type_safe_units.sio. -
Uncertainty (
Knowledge<T>): GUM propagation forf64,bool, and struct types is implemented. First-order derivatives cross function calls for pure helpers (see KNOWN_LIMITATIONS.md §KL-11 for call-boundary details). Second-order (Hessian) channels exist but have documented scope limits. -
Not implemented:
Knowledge<f128>and GUM over 128-bit floats (KL-15); wide float epistemic types remain on the roadmap. -
This is pre-1.0 software. Expect breaking changes, incomplete surfaces, and documented limitations. See KNOWN_LIMITATIONS.md for the current open-item ledger.