Skip to content

Units and Quantities Principles

kwikius edited this page Sep 7, 2025 · 13 revisions

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.

  1. Numerics

    Numerics are the most primitive Quantities. Numerics can be integers or floating point types. Numerics may be further refined into other Quantities.

  2. 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.
    • Dimensions may be simpleDimensions or customDimensions

Examples

Length        = { L:1 }
Velocity      = { L:1, T:-1 }
Square root L = { L:1/2 }
  1. 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 ={1/1,0/1} )
unit s   = ( {T:1}, conversion_factor ={1/1,0/1} )
unit in  = ( {L:1}, conversion_factor ={254/10000,1/1} )   // 0.0254 m
unit mph = :mi/h:                        // alias expands to scale factor × SI
  1. 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:;
  1. 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.
  2. 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.
  3. 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:

  4. 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.
  1. 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

  1. 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.

Clone this wiki locally