-
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.
-
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 need not be ordered; lookup is by base dimension.
Examples
Length = { L:1 }
Velocity = { L:1, T:-1 }
Square root L = { L:1/2 }
-
Units
A unit = (dimension, scale factor). A scaling 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 rational scale factor relative to SI.
Examples
unit m = ( {L:1}, scale=1 )
unit s = ( {T:1}, scale=1 )
unit in = ( {L:1}, scale=254/10000 ) // 0.0254 m
unit mph = :mi/h: // alias expands to scale factor × SI
-
Quantities
A quantity = (numeric value of some 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 → int32This 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.