739-phantom-units-of-measure — Phantom Units of Measure
Tutorial Video
Text description (accessibility)
This video demonstrates the "739-phantom-units-of-measure — Phantom Units of Measure" functional Rust example. Difficulty level: Advanced. Key concepts covered: Functional Programming. The Mars Climate Orbiter was lost in 1999 because one module computed thrust in pound-force seconds and another expected newton-seconds. Key difference from OCaml: 1. **Language support**: F# has first
Tutorial
The Problem
The Mars Climate Orbiter was lost in 1999 because one module computed thrust in pound-force seconds and another expected newton-seconds. Unit confusion errors cost lives and billions of dollars. F# pioneered Units of Measure as a language feature; Rust and OCaml achieve the same protection via phantom types. A Length<Meters> cannot be added to Length<Feet> without an explicit conversion, catching unit errors at compile time with zero runtime overhead.
🎯 Learning Outcomes
Meters, Feet, Kilograms)Length<M> + Length<M> -> Length<M>Length<Meters> + Length<Feet> fails)Code Example
#![allow(clippy::all)]
//! # Phantom Units Of Measure
pub fn placeholder() -> &'static str {
"phantom-units-of-measure implementation"
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_placeholder() {
assert!(!placeholder().is_empty());
}
}Key Differences
Meters * Meters = MetersSquared via trait implementations; OCaml requires more verbose GADT indices to express multiplication of units.uom (units of measurement) and dimensioned crates with full SI unit coverage; OCaml has no equivalent widely-used crate.OCaml Approach
F# has native units-of-measure syntax ([<Measure>] type m and float<m>). OCaml lacks this but achieves it via phantom types: type 'u length = Length of float. Jane Street's Validated and units-sexp libraries provide similar functionality. The OCaml community often uses Gg library for 3D geometry with typed vectors. GADTs allow encoding unit arithmetic relationships directly.
Full Source
#![allow(clippy::all)]
//! # Phantom Units Of Measure
pub fn placeholder() -> &'static str {
"phantom-units-of-measure implementation"
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_placeholder() {
assert!(!placeholder().is_empty());
}
}#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_placeholder() {
assert!(!placeholder().is_empty());
}
}
Deep Comparison
Units of Measure
See example files for comparison.
Exercises
Time<Seconds> and implement Velocity<MetersPerSecond> as the result of dividing Length<Meters> by Time<Seconds>.Celsius to Fahrenheit conversion that changes the phantom type: fn to_fahrenheit(t: Temperature<Celsius>) -> Temperature<Fahrenheit>.force function that multiplies Mass<Kilograms> by Acceleration<MetersPerSecondSquared> and returns Force<Newtons>.