### Units

 Definition Expression Alias Assert Example

Ocean can do automatic (almost zero overhead) checking on numbers with units. Each numeric variable can have a unit and units are checked for correctness during expression evaluation. Units can be 'elementary' or 'derived', but they are always stored in their 'elementary' unit, so using integers with a derived unit can result in incorrect behavior (Ocean will do some sanity checks, but caveat emptor).

#### Expression

The 'generic-id' unit-label is used in parameter definitions:

```define function add(my SNWord `@1`, my SNWord `@1`, return SNWord `@1`);
define function multiply(my SNWord `@1`, my SNWord `@2`, return SNWord `@1*@2`);
```

Where add must have two input arguments with identical units, and multiply can have two input arguments of any unit, and will return a value with a 'mutiplied-unit' unit.

##### Unit-label aspects
Step 1 of conversion of a literal expressed in the unit, to be converted to base unit, expressed as a lit-real.
unify_mul2
Step 2 of conversion of a literal expressed in the unit, to be converted to base unit, expressed as a lit-real.
unify_div3
Step 3 of conversion of a literal expressed in the unit, to be converted to base unit, expressed as a lit-real.
unify_sub4
Step 4 of conversion of a literal expressed in the unit, to be converted to base unit, expressed as a lit-real.
Step 1 of conversion of a stored value, to be converted to a value expressed in the derived unit, expressed as a lit-real.
derive_mul2
Step 2 of conversion of a stored value, to be converted to a value expressed in the derived unit, expressed as a lit-real.
derive_div3
Step 3 of conversion of a stored value, to be converted to a value expressed in the derived unit, expressed as a lit-real.
derive_sub4
Step 4 of conversion of a stored value, to be converted to a value expressed in the derive unit, expressed as a lit-real.
short_name
The short name of the unit, expressed as a lit-text.
long_name
The long name of the unit, expressed as a lit-text.

It is evident that ::unify_add1 is identical to ::derive_sub4 etcetera, but for readability both sets are present.

Note that all expressed values are given in the best guaranteed precision, with integers having infinite precision. So a 1 digit precision value of '1' would be expresses as '0.1E1'.

#### Assert

Sanity checking during compile time, left and right side should be identical in value.

#### Examples

```define unit meter | m;
define unit second | s;
alias unit mile | ml = `m` / 1600;          # You can use both short
alias unit minute | min = `second` / 60;    # or long ordinal-ids
alias unit hour | hr = `minute` / 60;       # Alias on an alias is just fine
alias unit mile_per_hour | mph = `ml/hr`    # and compound is valid too
the float speed `mph` = 60 `m/min`;         # Odd, but valid, speed == 1 (!),
# but prints as "2.25"
define unit kelvin | \u0212A;               # same zero is not necessary
alias unit celcius | \u02103 = `kelvin` - 27315e-2;
alias unit fahrenheit | \u02109 = `celcius` *9/5 + 32;
# Note that these computations
# are infinite precise
define unit degree | deg;                   # But this conversion is
alias unit radian | rad = degree * 2 * 3.141592 / 360;  # not!

assert unit 1 `mph` = 1600 `m/hour`;        # Sanity checks, evaluated at
assert unit 3600 `m/h` = 1 `m/s`;           # compile time (no runtime code)
assert unit 68 `fahrenheit` = 293.15 `kelvin`;
```