-
Notifications
You must be signed in to change notification settings - Fork 0
Units and Quantities Principles
Units and Quantities – Design Principles (Draft)
This page outlines the draft design rules for quantities and units in gzScript. The aim is to provide a strongly typed, S.I. oriented system that prevents errors while staying expressive enough for simulation scripting.
-
Numerics
Numerics are the most primitive Quantities. Numerics can be integers or floating point types. Numerics may be further refined into other Quantities.
-
Dimensions
- A dimension is represented as a mapping from base dimensions → rational exponents.
- Each base dimension is unique. If a base dimension is not present, its exponent is 0.
- Tuples representing dimensions need not be ordered; lookup is by base dimension.
- Dimensions may be simpleDimensions or customDimensions
Examples
Length = { L:1 }
Velocity = { L:1, T:-1 }
Square root L = { L:1/2 }
-
Units
A unit = (dimension, conversion factor). A conversion factor = {rational multiplier,rational exponent} SI base units always have a multiplier = 1/1 and an exponent = 0/1. Non-SI units are defined by a conversion factor relative to SI.
Examples
unit m = ( {L:1}, conversion_factor ={multiplier = 1/1, exponent = 0/1} )
unit s = ( {T:1}, conversion_factor ={multiplier = 1/1, exponent =0/1} )
unit in = ( {L:1}, conversion_factor ={multiplier = 127/50, exponent = -2/1} ) // 0.0254 m
unit mi = ( {L:1}, conversion_factor = {multiplier = 463/250, exponent = 3/1} )
unit h = ( {T:1}, conversion_factor ={multiplier = 18/5, exponent =3/1} )
unit mph = :mi/h: // alias expands to scale factor × SI
-
Quantities
- A quantity = (numeric value of some numeric type T , unit).
- Numeric type and unit type are both part of the type system.
- The default si quantities are known as anonymous quantities.
Examples
v = 5:m/s:;
d = 25.4:mm:;
-
Refinements
- Refinements are semantic subtypes of a dimension.
- A refinement adds meaning (e.g. height vs width) without changing the underlying dimension.
- A refinement provides an extra level of type safety where required.
Rules
- A height can be initialised from an anonymous Length.
- A width can be initialised from an anonymous Length or another width.
- A height cannot be initialised directly from a width.
- Multiplication/division that changes the dimension always produces an anonymous result.
-
Numeric Literals
- An integer literal is assigned the smallest integer type that can exactly hold it.
Examples
1 → int8 256 → int16 70000 → int32- This avoids unnecessary narrowing conversions.
- Floating point literals follow similar principles, but details require care.
-
Operations
Addition, subtraction, comparison Only allowed between quantities of the same refinement or within the same refinement tree. Result keeps the refinement type. Adding mismatched refinements (e.g. height + width) is a compile error.
Multiplication, division Produces an anonymous quantity with derived dimension. Example: 2:m: * 3:m: → 6:m^2:
Mixed-unit operations If units differ, operands are converted to SI before operation. Example: 2:ft: + 1:m: → 1.6096:m:
-
Angles
Angles are a special case, treated as refinements of dimensionless:
Radian family (rad, sr, …)
Interchangeable with dimensionless.
May be implicitly promoted/demoted.
Fraction-of-revolution family (deg, turn, …)
Not interchangeable with dimensionless.
Convertible to radians by explicit scaling.
-
SI Preference
SI is the canonical system.
Operations collapse to SI unless: Both operands share the exact same non-SI unit, and the operation preserves that unit (e.g. addition). The result is explicitly assigned to a non-SI unit.
Examples
2:ft: + 3:ft: → 5:ft: 2:ft: * 3:ft: → 0.092903:m^2: // SI 2:ft: + 1:m: → 1.6096:m: // SI
- Examples
v = 5:m/s:; t = 2:s:;
// anonymous result d = v * t; // = 10:m: (anonymous length)
// refined quantities h:height: = 1.75:m:; w:width: = 0.30:m:;
// error: height cannot be initialised from width w = h; // compile error
// angles theta = 180:deg:; phi = 3.14:rad:; x = sin(phi); // ok, rad ↔ dimensionless y = sin(theta); // requires conversion deg → rad
Status
This page is a living draft. The rules here will evolve as gzScript matures.