Defining Custom Units and Scales
While Zigma comes out-of-the-box with standard SI base dimensions (Length, Mass, Time, etc.) and common scales, you will often encounter domain-specific units or need to track non-physical quantities—like currencies, computational bytes, or custom business metrics.
Here is how to extend Zigma's dimensional engine to fit your exact needs.
1. Creating Custom Dimensions
You can define entirely new, independent base dimensions using the dimension keyword.
Once defined, Zigma's compile-time safety applies to them just like physical units.
For example, let's track finances without accidentally adding US Dollars to Euros:
dimension usd
dimension eur
wallet = 100 usd
coffee = 3 eur
// Compile-Time Error: Cannot add [usd] to [eur]!
remaining = wallet - coffee
2. Defining Aliases & Conversions
Writing out kg.m2/s2 every time you want to calculate energy or torque gets tedious.
You can use the alias keyword to create shorthand names for existing dimension combinations.
alias Tq as kg.m2/s2 // Torque
alias J as kg.m2/s2 // Joule
work = 50 J
torque = 10 Tq
// Because both map to the same underlying dimensions (M·L²/T²),
// Zigma safely allows them to interact!
total = work + torque
Conversion Rates between Custom Dimensions
You can also use alias to create conversion rates between independent custom dimensions.
Let's fix the currency error from earlier by giving Zigma the exchange rate:
dimension usd
alias eur as usd * 1.08
wallet = 100 eur
coffee = 10 usd
// Zigma auto-converts the units based on the alias multiplier
leftover = wallet - coffee
print "{leftover}" // Returns 98 usd
3. Advanced Aliases (Formulas)
Some conversions require more than just a multiplier. For example, temperatures often have offsets. You can define aliases as full formulas. Zigma will automatically apply the underlying math whenever a conversion happens.
alias degC as K - 273.15
alias Fahr as K * 9/5 - 459.67
t_kelvin = 300 K
t_celsius = t_kelvin in degC // Automatically subtracts 273.15
print "{t_celsius}" // 26.85 degC
4. Defining Custom Scales
Sometimes you don't want a new dimension or an alias, you just want to define a specific scale for an existing dimension. Zigma allows you to define both custom prefixes (applicable to any dimension) and unique scales (tied to a specific dimension).
Prefix Scales
A prefix scales the value by a raw multiplier, regardless of the dimension.
// E.g., defining a custom multiplier
scale milli as 0.001
a = 5 millim // Evaluates to 0.005 m
b = 2 millis // Evaluates to 0.002 s
Unique Scales
A unique scale is strictly bound to a specific base dimension (like Time or Length).
// Defining a custom time scale for a simulation
scale year as 3.154e7 for s
age = 5 year
// Zigma knows 'year' is just a scale of Time [s]
age_in_seconds = age in s
Explicit is better than implicit
Zigma's philosophy is to automatically use the best/smallest scale during operations to prevent data loss.
However, when working with complex custom units, it's a good habit to explicitly cast your final results using
in or as to ensure the output is exactly what you expect (e.g., result = a + b in eur).