Skip to content

Physical Units (std.unit)

The std.unit module provides built-in, first-class support for physical units, quantities, and dimensional analysis directly within Flame.


Flame’s unit system allows you to create quantities that carry physical units (like meters, seconds, and kilograms). This ensures dimensional safety, meaning that the runtime automatically checks for incompatible operations (e.g. adding meters to seconds) and will throw an error to prevent logical bugs in calculations.

Out of the box, std.unit provides the base SI units as constants:

  • unit.meter: The SI base unit for length (m).
  • unit.second: The SI base unit for time (s).
  • unit.kilogram: The SI base unit for mass (kg).
import std.unit
let length = 10 * unit.meter
let time = 5 * unit.second

You can use standard math operators (+, -, *, /) with quantities.

When adding or subtracting, the units must match exactly. If you try to add quantities with different units, Flame will throw a runtime error.

import std.unit
let distance1 = 15 * unit.meter
let distance2 = 5 * unit.meter
let total_distance = distance1 + distance2
println(total_distance) // 20 m
// This will throw a runtime error: "cannot add quantities with different units"
// let error = distance1 + (5 * unit.second)

When multiplying or dividing, the units naturally combine or cancel out.

import std.unit
let distance = 100 * unit.meter
let time = 10 * unit.second
// Division results in a new unit: m * s^-1
let speed = distance / time
println(speed) // 10 m * s^-1

If the units cancel out completely, Flame will automatically downgrade the quantity back to a regular Float.

import std.unit
let length1 = 10 * unit.meter
let length2 = 2 * unit.meter
let ratio = length1 / length2
println(ratio) // 5.0 (scalar float, no units)

If you need a compound unit or one that isn’t provided by default, you can construct custom unit equations using the unit.Equation(kg, m, s) function.

You pass the exponents for kilograms (kg), meters (m), and seconds (s) in that order.

import std.unit
// Speed: m/s -> kilograms^0, meters^1, seconds^-1
let speed_unit = unit.Equation(0, 1, -1)
// Acceleration: m/s^2 -> kilograms^0, meters^1, seconds^-2
let accel_unit = unit.Equation(0, 1, -2)
// Newton: kg * m/s^2 -> kilograms^1, meters^1, seconds^-2
let newton = unit.Equation(1, 1, -2)
let my_speed = 50 * speed_unit

If you need to discard the dimensional information and work purely with the underlying magnitude of a quantity, you can use the built-in primitive conversion methods like toFloat(), tryFloat(), toInt(), and tryInt().

import std.unit
let distance = 10.5 * unit.meter
// Drops the "meter" unit and returns the raw float value
let val = distance.toFloat()
println(val) // 10.5

Flame’s math module (std.math) is unit-aware. When you pass units or quantities into mathematical functions and operators, Flame automatically calculates, scales, and validates their physical dimensions.

Exponentiation and Powers (^ and math.pow)

Section titled “Exponentiation and Powers (^ and math.pow)”

You can raise units and quantities to integer powers using the ^ operator or math.pow(). The exponent scales both the underlying magnitude and the unit powers:

import std.unit
import std.math
// 1. Exponentiation on base units
let s2 = unit.second^2 // seconds squared (s^2)
let m3 = unit.meter^3 // cubic meters (m^3)
// 2. Exponentiation on quantities (scales magnitude and unit)
let area = (4 * unit.meter)^2
println(area) // 16 m^2
// 3. Using math.pow for dynamic or explicit powers
let volume = math.pow(3 * unit.meter, 3)
println(volume) // 27 m^3

math.sqrt() evaluates the square root of numbers, quantities, and units with even dimensional powers. Each dimension’s exponent is safely halved:

import std.unit
import std.math
// Square root of a unit dimension
let s = math.sqrt(unit.second^2)
println(s) // 1 s
// Pendulum period calculation: T = 2 * pi * sqrt(L / g)
let L = 2 * unit.meter
let g = 9.81 * unit.meter / unit.second^2
// L / g produces a quantity in s^2
// math.sqrt(s^2) safely propagates the dimension and returns a quantity in seconds (s)
let T = 2 * math.pi() * math.sqrt(L / g)
println(T) // ~ 2.837 s

math.abs() computes the absolute value while strictly preserving unit dimensions:

import std.unit
import std.math
let neg_speed = -25.5 * (unit.meter / unit.second)
let speed = math.abs(neg_speed)
println(speed) // 25.5 m/s

Dimension Checking & Extremums (math.min and math.max)

Section titled “Dimension Checking & Extremums (math.min and math.max)”

Functions like math.min() and math.max() compare quantities and units of matching physical dimension:

import std.unit
import std.math
let length1 = 15 * unit.meter
let length2 = 5 * unit.meter
let time = 10 * unit.second
// This works perfectly (same dimension: length)
let longest = math.max(length1, length2)
println(longest) // 15 m
let shortest = math.min(length1, 5 * unit.meter)
println(shortest) // 5 m
// Comparing a quantity directly against a base unit (which has magnitude 1.0)
let at_least_meter = math.max(0.5 * unit.meter, unit.meter)
println(at_least_meter) // 1 m
// This throws a runtime error (cannot compare meters and seconds)
// let error = math.max(length1, time)

Trigonometric Functions (math.sin & math.cos)

Section titled “Trigonometric Functions (math.sin & math.cos)”

Trigonometric functions like math.sin() and math.cos() strictly require a dimensionless input (e.g., an angle where all units have completely canceled out). If you supply a quantity with active units, the runtime will throw a dimensional error.

Method / Constant Description
unit.meter Constant representing the base unit for length (meters).
unit.second Constant representing the base unit for time (seconds).
unit.kilogram Constant representing the base unit for mass (kilograms).
unit.Equation(kg, m, s) Returns a new custom unit composed of the exponents provided for kilograms, meters, and seconds.
unit ^ n Raises a unit to the integer power n (e.g. unit.second^2).
quantity ^ n Raises a quantity to power n, scaling magnitude and dimensional powers (e.g. (4 * unit.meter)^2).
math.pow(base, exp) Raises a quantity or unit to an exponent while maintaining dimensional integrity.
math.sqrt(q) Computes the square root, halving each even-powered unit dimension (e.g. math.sqrt(s^2) -> s).
math.abs(q) Computes the magnitude of a quantity while preserving its unit.
math.min(a, b) Returns the lesser of two quantities or units with identical physical dimensions.
math.max(a, b) Returns the greater of two quantities or units with identical physical dimensions.