Defining New Units (Units: A Unit Conversion Program and Scientific Calculator)

### 14.2 Defining New Units and Prefixes ¶

A unit is specified on a single line by giving its name and an equivalence. Comments start with a ‘`#`’ character, which can appear anywhere in a line. The backslash character (‘`\`’) acts as a continuation character if it appears as the last character on a line, making it possible to spread definitions out over several lines if desired. A file can be included by giving the command ‘`!include`’ followed by the file’s name. The ‘`!`’ must be the first character on the line. The file will be sought in the same directory as the parent file unless you give a full path. The name of the file to be included cannot contain spaces or the comment character ‘`#`’.

Unit names cannot begin or end with an underscore (‘`_`’) or a decimal point (‘`.`’), and cannot contain any of the operator characters ‘`+`’, ‘`-`’, ‘`*`’, ‘`/`’, ‘`|`’, ‘`^`’, ‘`;`’, ‘`~`’, a comma (‘`,`’), the comment character ‘`#`’, or parentheses. To facilitate copying and pasting from documents, several typographical characters are converted to operators: the figure dash (U+2012), minus (‘`\(-\)`’; U+2212), and en dash (‘–’; U+2013) are converted to the operator ‘`-`’; the multiplication sign (‘`×`’; U+00D7), N-ary times operator (U+2A09), dot operator (‘`⋅`’; U+22C5), and middle dot (‘`·`’; U+00B7) are converted to the operator ‘`*`’; the division sign (‘`÷`’; U+00F7) is converted to the operator ‘`/`’; and the fraction slash (U+2044) is converted to the operator ‘`|`’; accordingly, none of these characters can appear in unit names.

Names cannot begin with a digit, and if a name ends in a digit other than zero or one, then the name must end with an underscore followed by a string consisting only of digits and decimal points. For example, ‘`foo_2`’, ‘`foo_3.14`’, and ‘`foo_3...9`’ are valid names but ‘`foo2`’ or ‘`foo_a2`’ are invalid. The underscore is necessary because without it, `units` cannot determine whether ‘`foo2`’ is a unit name or represents ‘`foo^2`’. Zero and one are exceptions because `units` never interprets them as exponents.

You could define nitrous oxide as

    N2O     nitrogen 2  + oxygen

but would need to define nitrogen dioxide as

    NO_2    nitrogen + oxygen 2

Be careful to define new units in terms of old ones so that a reduction leads to the primitive units, which are marked with ‘`!`’ characters. Dimensionless units are indicated by using the string ‘`!dimensionless`’ for the unit definition.

When adding new units, be sure to use the `-c` option to check that the new units reduce properly and that there are no circular definitions that lead to endless loops. Because some errors may hide other errors, you should run `units` with the `-c` option again after correcting any errors, and keep doing so until no errors are displayed.

If you define any units that contain ‘`+`’ characters in their definitions, carefully check them because the `-c` option will not catch non-conformable sums. Be careful with the ‘`-`’ operator as well. When used as a binary operator, the ‘`-`’ character can perform addition or multiplication depending on the options used to invoke `units`. To ensure consistent behavior use ‘`-`’ only as a unary negation operator when writing units definitions. To multiply two units leave a space or use the ‘`*`’ operator with care, recalling that it has two possible precedence values and may require parentheses to ensure consistent behavior. To compute the difference of ‘`foo`’ and ‘`bar`’ write ‘`foo+(-bar)`’ or even ‘`foo+-bar`’.

You may wish to intentionally redefine a unit. When you do this, and use the `-c` option, `units` displays a warning message about the redefinition. You can suppress these warnings by redefining a unit using a ‘`+`’ at the beginning of the unit name. Do not include any white space between the ‘`+`’ and the redefined unit name.

Here is an example of a short data file that defines some basic units:

    m       !               # The meter is a primitive unit
    sec     !               # The second is a primitive unit
    rad     !dimensionless  # A dimensionless primitive unit
    micro-  1e-6            # Define a prefix
    minute  60 sec          # A minute is 60 seconds
    hour    60 min          # An hour is 60 minutes
    inch    72 m            # Inch defined incorrectly terms of meters
    ft      12 inches       # The foot defined in terms of inches
    mile    5280 ft         # And the mile
    +inch   0.0254 m        # Correct redefinition, warning suppressed

A unit that ends with a ‘`-`’ character is a prefix. If a prefix definition contains any ‘`/`’ characters, be sure they are protected by parentheses. If you define ‘`half- 1/2`’, then ‘`halfmeter`’ would be equivalent to ‘`1 / (2 meter)`’.