Discerning Quantities from Units of Measurement
Steve McKeever
a
Department of Informatics and Media, Uppsala University, Sweden
Keywords:
Quantities, Units of Measurement, Quantity Checking, Dimensional Analysis.
Abstract:
In scientific and engineering applications, physical quantities embodied as units of measurement (UoM) are
frequently used. While managing units of measurement is a fairly mature topic in software engineering, more
subtle metrological concepts such as named quantities have had little traction within the scientific program-
ming community. The loss of the Mars climate orbiter, attributed to a confusion between the metric and
imperial unit systems, popularised the disastrous consequences of incorrectly handling measurement values.
This has led to the development of a large number of libraries, languages and tools to ensure developers can
specify and validate UoM information in their designs and codes. However these systems do not differentiate
between quantities and dimensions. For instance torque and work, which share the same UoM, can not be
interchanged because they do not represent the same entity. We present a named quantity layer that sits on
top of a dimension checker and unit converter ensuring values of different quantities are correctly managed
without undue restrictions. Our quantity algebra works alongside the unit dimensions to ensure we maintain
named quantities when we perform arithmetic and function calls.
1 INTRODUCTION
Humans have used local units of measurement since
the days of early trade, enhanced over time to fulfil the
accuracy and interoperable needs of science and tech-
nology. The technical definition of a physical quantity
is a “property of a phenomenon, body, or substance,
where the property has a magnitude that can be ex-
pressed as a number and a reference” (Joint Commit-
tee for Guides in Metrology (JCGM), 2012) Ensur-
ing numerical values that denote physical quantities
are handled correctly is an essential requirement for
the design and development of any engineering ap-
plication. Infamous examples such as the Mars Cli-
mate Orbiter (Stephenson et al., 1999) or the Gimli
Glider incident (Witkin, 1983) substantiate this. With
ubiquitous digitalisation, and removal of humans in
the loop, the need to faithfully represent and manipu-
late quantities in physical systems is ever increasing.
Programming languages allow developers to describe
how to evaluate numeric expressions but not how to
detect inappropriate actions on quantities.
Dimensions are physical quantities that can be
measured, while units are arbitrary labels that corre-
spond to a given dimension to make it relative. For
example a dimension is length, whereas a metre is
a
https://orcid.org/0000-0002-1970-2884
a relative unit that describes length. Units of mea-
sure can be defined in the most generic form as ei-
ther base quantities or derived quantities. The base
quantities are the basic building blocks, and the de-
rived quantities are built from these. The base quanti-
ties and derived quantities together form a way of de-
scribing any part of the physical world (Sonin, 2001).
For example length (metre) is a base quantity, and
so is time (second). If these two base quantities
are combined they express velocity (metre/second or
metre × second
1
) which is a derived quantity. The
International System of Units (SI) defines seven base
quantities (length, mass, time, electric current, ther-
modynamic temperature, amount of substance, and
luminous intensity) as well as a corresponding unit for
each quantity (NIST, 2015). Some popular examples
of both base and derived units are shown in Table 1.
It is common for quantities to be declared as a num-
ber (the magnitude of the quantity) with an associ-
ated unit (Bureau International des Poids et Mesures,
2019).
There are many ways in which software processes
and development can accommodate units of measure-
ment in this manner (McKeever, 2021). Adding units
to conventional programming languages goes back to
the 1970s (Karr and Loveman, 1978) and early 80s
with proposals to extend Fortran (Gehani, 1977) and
McKeever, S.
Discerning Quantities from Units of Measurement.
DOI: 10.5220/0010971300003119
In Proceedings of the 10th International Conference on Model-Driven Engineering and Software Development (MODELSWARD 2022), pages 105-115
ISBN: 978-989-758-550-0; ISSN: 2184-4348
Copyright
c
2022 by SCITEPRESS Science and Technology Publications, Lda. All rights reserved
105
Table 1: Some SI standard base and derived units.
Name Symbol Quantity Base Units
metre l length metre
kilogram m mass kg
second t time second
hertz Hz frequency second
1
newton N force, weight metre × kg × second
2
pascal Pa pressure, stress metre
1
× kg × second
2
joule J energy, work metre
2
× kg × second
2
newton metre N m torque metre
2
× kg × second
2
watt W power, radiant flux metre
2
× kg × second
3
square metre m
2
area metre
2
cubic metre m
3
volume metre
3
metre per second
m/s speed, velocity metre × second
1
metre per second squared
m/s
2
acceleration metre × second
2
then Pascal (Dreiheller et al., 1986). Hilfinger (Hil-
finger, 1988) showed how to exploit Ada’s abstrac-
tion facilities, namely operator overloading and type
parameterisation, to assign attributes for UoM to vari-
ables and values. The emergence of object oriented
programming languages enabled developers to imple-
ment UoM either through a class hierarchy of units
and their derived forms, or through the Quantity pat-
tern (Fowler, 1997). There are a large number of li-
braries for all popular object oriented programming
languages (Bennich-Bj
¨
orkman and McKeever, 2018)
that support this approach (McKeever et al., 2019).
Applying UoM annotations requires an advanced
checker to ensure variables and method calls are han-
dled soundly. Two units are compatible if they both
can be represented as the same derived quantity. For
instance degrees Celsius is compatible with Fahren-
heit. Values in Celsius can be converted to values in
Fahrenheit. Two values can be added or subtracted
only if their units are the same. Multiplication and di-
vision either add or subtract the two units product of
power representations, assuming both values are com-
patible. Once a variable has been defined to be of a
given unit, then it should remain as such. Checking
that all annotated entities behave according to these
rules ensures both completeness and correctness of
the programme, and can be undertaken before the
code is run.
However two values that share the same UoM
might not represent the same ‘kinds of quantities’.
For example, torque is a rotational force which causes
an object to rotate about an axis while work is the
result of a force acting over some distance. Surface
tension can be described as newtons per meter or
kilogram per second squared, and even though they
equate, they represent different quantities. Our focus
is to present a simple set of rules for arithmetic and
function calls that allow quantities to be named and
handled correctly.
This paper is structured as follows, in Section 2 we
describe how UoM are typically implemented and ar-
gue for a more comprehensive representation, while
acknowledging the drawbacks of adding complexity
to the development process. In Section 3 we introduce
unit expressions and dimensional analysis. In Sec-
tion 4 we describe a simple algebra of named quan-
tities. and show how they can be maintained while
evaluating unit assignments and function calls. We
also discuss some of the obstacles to implementing
named quantities and UoM in general. Finally, in Sec-
tion 5 we summarise quantity validation and describe
avenues of current research.
2 BACKGROUND
One can assert the physical dimension of length with
the unit metre and the magnitude 10 (10m). However,
the same length can also be expressed using other
units such as centimetres or kilometres, at the same
time changing the magnitude (1000cm or 0.01km).
Although these examples are all based on the Interna-
tional System of Units (SI) there exists several other
systems, such as the Imperial system where yards
and miles would be used. On this basis a very sim-
ple object oriented design would entail a superclass
for each dimension, such as Length, and then spe-
cific subclasses for the various units, each of which
would contain overloaded operators to ensure unit
based arithmetic could be performed correctly.
Length l1 = new LengthMetre (5.0);
Length l2 = new LengthYard (4.0);
Length l3 = l1.addlength (l2);
MODELSWARD 2022 - 10th International Conference on Model-Driven Engineering and Software Development
106
The addlength command would convert l2 into me-
tres and perform the addition. We could extend our
object oriented design to create a class hierarchy for
each base type and use a tree structure to construct
derived types. However this would result in hundreds
of units and thousands of conversions.
Fortunately, a normal form exists which makes
storage and comparison a lot easier. Any system of
units can be derived from the base units as a prod-
uct of powers of those base units: base
e
1
×base
e
2
×
... base
e
n
, where the exponents e
1
,.. .,e
n
are rational
numbers. Thus an SI unit can be represented as a 7-
tuple he
1
,.. .,e
7
i where e
i
denotes the i-th base unit;
or in our case e
1
denotes length, e
2
mass, e
3
time and
so on.
This tuple can be reflected in a typical program-
ming language as an array of integers. Although there
are rare instances when fractional exponents might be
required for intermediate results even when there is
no SI unit that requires them. Within an object ori-
ented class structure the array can be coupled with
conversion, equality and numeric operators to form a
Unit abstract data type which ensures only UoM cor-
rect arithmetic is undertaken. In Java this would be
represented as:
class Unit {
private int [7] dimension;
private float [7] conversionFactor;
private int [7] offset;
...
boolean isCompatibleWith (Unit u);
boolean equals (Unit u);
Unit multiplyUnits (Unit u);
Unit divideUnits (Unit u);
}
This is the basis of the Quantity pattern (Fowler,
1997) in which quantity values are represented as a
pair: the numerical value, {Q}, and the unit of mea-
sure, [Q], such that Q = {Q} · [Q].
class Quantity {
private float value;
private Unit unit;
....
}
The Quantity pattern provides a means of annotat-
ing variable declarations and method signatures with
behavioural UoM specifications. Most libraries for
modern programming languages implement this ap-
proach but, as was found in the survey of (Salah and
McKeever, 2020), do not satisfy the core require-
ments of the scientific programming community. In-
terview subjects felt that UoM libraries were inconve-
nient: they did not interact well with the eco-system,
had performance issues, required effort to learn and
costly rewrites to support. Increasing uptake for quan-
tity aware code requires a language neutral interface
that allows programmers to manage UoM in an indis-
tinguishable language agnostic fashion, either as part
of the core language (e.g. Swift (Apple, 2020) and
F# (Microsoft, 2020)) or through the use of a sepa-
rate validator (Jiang and Su, 2006; Dieterichs Hen-
ning, 2021; Hills M et al., 2012; Xiang et al., 2020)).
Moreover, language based solutions enable quantity
checking to be undertaken at compile-time, detecting
errors early while ensuring no run-time overheads are
required.
3 UNIT EXPRESSIONS
Performing calculations in relation to quantities, di-
mensions and units is often complex and can easily
lead to mistakes. A dimensional analysis needs to
check that (1) two physical quantities can only be
equated if they have the same dimensions; (2) two
physical quantities can only be added if they have the
same dimensions (known as the Principle of Dimen-
sional Homogeneity); (3) the dimensions of the mul-
tiplication of two quantities is given by the addition
of the dimensions of the two quantities. We shall be-
gin by defining dimensional analysis for a hypothet-
ical programming language extended with unit vari-
able declarations, udecs, and only consider the three
common base dimensions of length, mass and time.
Hence velocity, namely length × time
1
, is repre-
sented as (1,0,1). We use the standard float im-
plementation to approximate for real numbers but as
we are not performing arithmetic any representation
would suffice.
udecs ::= udec
1
; . ..; udec
m
udec ::= uv : float of (int, int, int)
The language has the standard statement con-
structs, stmt, and boolean expressions, bexp, but we
will only focus on quantity variable assignments and
conditionals as these affect unit variables, uv. We also
have explicit unit expressions, uexp. Unit arithmetic
expressions, uexp, impose syntactic restrictions so
that their soundness can be inferred using the algebra
of quantities. By creating a separate syntax for unit
expressions we can distinguish between scalar values
and unitless quantities, namely values that have the
dimensions (0,0,0) such as moisture content.
stmt ::= uv := uexp | . .. |
| if bexp then stmt
1
else stmt
2
uexp ::= uv | uexp
1
+uexp
2
| r*uexp | uexp
1
*uexp
2
In Figure 1 we present the dimension analysis
rules for declarations, assignments, conditionals and
Discerning Quantities from Units of Measurement
107
huv : real of d, ρi
udec
ρ {uv 7→ d} [Dim Var Decl]
hudec
1
, ρi
udec
ρ
1
··· hudec
m
, ρ
m1
i
udec
ρ
m
hudec
1
; . ..; udec
m
, ρi
udecs
ρ
m
[Dim Var Decls]
ρ ` uexp
uexp
(l,m,t) ρ uv = (l,m,t)
ρ ` uv := uexp
stmt
DimValid
[Valid Assign Stmt]
ρ ` uexp
uexp
(l,m,t) ρ uv 6= (l,m,t)
ρ ` uv := uexp
stmt
DimFail
[Fail Assign Stmt]
ρ ` stmt
1
stmt
DimValid ρ ` stmt
2
stmt
DimValid
ρ ` if bexp then stmt
1
else stmt
2
stmt
DimValid
[Valid Cond Stmt]
ρ ` uv
uexp
ρ uv [Dim Var Expr]
ρ ` uexp
1
uexp
(l,m,t) ρ ` uexp
2
uexp
(l,m,t)
ρ ` uexp
1
+ uexp
2
uexp
(l,m,t)
[Dim Add Expr]
ρ ` uexp
uexp
(l,m,t)
ρ ` r * uexp
uexp
(l,m,t)
[Dim Scaler Expr]
ρ ` uexp
1
uexp
(l
1
,m
1
,t
1
) ρ ` uexp
2
uexp
(l
2
,m
2
,t
2
)
ρ ` uexp
1
* uexp
2
uexp
(l
1
+ l
2
,m
1
+ m
2
,t
1
+t
2
)
[Dim Mult Expr]
Figure 1: Dimension Analysis rules for declarations, assignments and expressions.
expressions. The rules for declarations build an en-
vironment, ρ, mapping variables to their dimensions.
The environment will not change throughout the life-
time of the block. Thus, once a variable has been de-
fined to be of a given quantity, then it will remain as
such. Many library based systems allow programmers
to change the dimensions of unit variables as they
are objects of type Quantity, namely a mutable ar-
ray. The rules for statements return either DimValid
or DimFail depending on whether a given statement
uses quantities correctly or not. An assignment state-
ment is valid only if the quantity of the unit expression
is dimensionally homogeneous with the unit variable
that it is being assigned to, as shown in Valid Assign
Stmt. The rule for conditionals checks the dimen-
sional validity of both true and false statements. The
rule for unit variables is just a lookup on the quantity
environment ρ. The rule for addition ensures that both
the left hand and right hand side subexpressions have
the same quantities. Thus a proof tree cannot com-
plete if the arguments to + have different dimensions,
signifying a dimension error in the programme. The
rules for multiplication allow constants to be applied
and multiplying two unit expressions will create a
combined quantity, where each dimension is summed.
Dimension analysis would be sufficient if only
one unit system, such as the SI system, was re-
quired. In such cases the base units of metre, kilo-
gram and second could be implicit in implementa-
tions. Dimensionally correct unit expressions can
be evaluated in much the same way as normal arith-
metic expressions. As this is rarely the case in sci-
entific applications where a myriad of unit systems
and magnitudes are used, we need to perform unit
conversions before evaluating the arithmetic expres-
sion. This can be undertaken at compile-time (Cooper
and McKeever, 2008) or at run-time. Moreover
we need to declare the units alongside their dimen-
sions. A variable denoting torque would be stored
as {t 7→ ((Metre,2),(Kilogram,1), (Second,2))}
in the environment.
4 QUANTITY RULES
This section introduces named quantities, their rules
and how they are supported in a typical programming
language.
4.1 Expressions
We adopt a similar approach to (Foster, 2013; Hall,
2020) in that quantities should be represented as a
3-tuple, and not as a 2-tuple mentioned previously.
Consequently we add a quantity name, hQi,to the nu-
MODELSWARD 2022 - 10th International Conference on Model-Driven Engineering and Software Development
108
τ ` uv
nexp
τ uv [Named Var Expr]
τ ` uexp
1
nexp
Named n τ ` uexp
2
nexp
Named n
τ ` uexp
1
+ uexp
2
nexp
Named n
[Named Add Expr]
τ ` uexp
1
nexp
Named n τ ` uexp
2
nexp
Noname
τ ` uexp
1
+ uexp
2
nexp
Named n
[Named Add Expr]
τ ` uexp
1
nexp
Noname τ ` uexp
2
nexp
Named n
τ ` uexp
1
+ uexp
2
nexp
Named n
[Named Add Expr]
τ ` uexp
1
nexp
Noname τ ` uexp
2
nexp
Noname
τ ` uexp
1
+ uexp
2
nexp
Noname
[Named Add Expr]
τ ` nexp
uexp
qn
τ ` r * uexp
nexp
qn
[Named Scaler Expr]
τ ` uexp
1
nexp
qn
1
τ ` uexp
2
nexp
qn
2
τ ` uexp
1
* uexp
2
nexp
Noname
[Named Mult Expr]
Figure 2: Named quantity rules for unit expression.
merical value, {Q}, and the unit of measure, [Q], such
that Q = hQi · {Q} · [Q].
However, not all quantity variables in a pro-
gramme will have a name such as Torque or Work.
Some might denote an entity such as length that could
be in metres or yards, while another might be a vari-
able used to store some temporary value. Neither of
these need to be named. Using an algebraic data type,
we define named quantities as:
type quantname = Named of string | Noname
We are now in a position to define the rules for adding
and multiplying named quantities. In both cases we
assume that the unit expression is dimensionally cor-
rect, our concern is to define how named quantities
conduct themselves. The operator 3 takes two named
quantities and defines how they compare: two named
quantities can be added together only if they represent
the same entity, if one quantity is named but the other
is not then it is necessary for the result to be named,
and if both are unnamed then the result will be too:
Named n
1
3 Named n
2
= Named n
1
, if n
1
= n
2
Named n
1
3 Named n
2
= ERROR, if n
1
6= n
2
Named n 3 Noname = Named n
Noname 3 Named n = Named n
Noname 3 Noname = Noname
Our comparison rules cast upwards from Noname to
Named, so as to assume a named quantity whenever
possible. This is required to ensure named quanti-
ties behave correctly. If we cast downwards then we
would have the alternative rule Named n 3 Noname =
Nonamed, that would allow Work to be added to
Torque through associativity:
Named "Work" 3 (Named "Torque" 3 Noname)
= Named "Work" 3 Noname
= Noname
For multiplication the rules are simpler. The oper-
ator 4 takes in two named quantities and defines how
they behave over the multiplication operator. As mul-
tiplication sums the dimensions of the two operands,
the value will be different to either and so the result
will always be Noname.
Named n
1
4 Named n
2
= Noname
Named n 4 Noname = Noname
Noname 4 Named n = Noname
Noname 4 Noname = Noname
The named quantity algebra can be incorporated into
our language as shown in Figure 2. The language
rules for scaler multiplication do not change the
named quantity, the scaler value only affects the quan-
tity value when evaluating expressions. Consider
the example where τ = {t 7→ Named "Torque",w 7→
Named "Work"}. If we were to try to perform t + w
then the rules for Named Add Expr will not suc-
ceed as upon retrieving their respective incompatible
quantnames, no rule will apply.
Assignment statements have to satisfy the named
quantity of the variable being assigned to, specifically
the left hand side, and can therefore either succeed or
fail:
type assignstate = Succeed | Fail
The rules specify that one can assign a named
quantity to a variable that has the same named quan-
tity but not otherwise. One can assign a Noname value
Discerning Quantities from Units of Measurement
109
to a named quantity variable as it will have the same
dimensions.
Named n
1
Named n
2
= Succeed, if n
1
= n
2
Named n
1
Named n
2
= Fail, if n
1
6= n
2
Named n Noname = Succeed
Noname Noname = Succeed
It might seem as if we are missing a rule for assign-
ing a named quantity to an unnamed variable but we
cannot allow Noname Named n to Succeed as this
would allow one to assign a Torque value to a Work
variable through the intermediary of a local unnamed
variable. This realisation has a profound effect on
how we define our programming language rules to
support the named quantity algebra. One must update
the environment τ to reflect that the named quantity
assignment has taken place, as shown in the fourth
Valid Assign Stmt rule of Figure 3. This ensures that
the bindings of unnamed values will reflect their us-
age and protect the code from erroneous assignments.
In order to guarantee coherence of potential changes
to bindings in τ, the environment is threaded through
the rule for conditionals.
4.2 Function Calls
Quantity functions, ufun, differ from normal func-
tions in that they can take a number of quantity ar-
guments, and return a quantity. We must make sure
that named quantities, qn, are passed into functions
correctly. Namely that the named quantity of each
argument matches that of its parameter. The quan-
tity rules will calculate a return named quantity, if the
function body satisfies the quantity algebra. Both a
definition mechanism and an invocation mechanism
are necessary for named quantity functions, as shown
in the rules QuantFDef and QuantFCall of Figure 4.
ufun ::= fun ufn(uv
1
:qn
1
,.. .,uv
m
:qn
m
)
is uexp
uexp ::= . .. | ufn(uexp
1
,.. .,uexp
m
)
We require a second environment, σ, to store the rele-
vant quantity information belonging to each quantity
function. The rules for expressions and assignments
will need to be extended to pass this second environ-
ment around but otherwise stay unchanged.
In order to guarantee quantity functions are
handled correctly by the main programme we
need to check that each invocation’s named
quantity arguments can be assigned to those
in the function definition. For a function call
ufn(uexp
1
,.. .,uexp
m
) and corresponding definition
header fun ufn(uv
1
:qn
1
,.. .,uv
m
:qn
m
), we must
ensure that the named quantity of each argument
uexp
i
, which we will infer to be qexp
i
can be assigned
to each parameter, namely uv
i
qexp
i
as shown in
Figure 4.
To illustrate how these collection of rules
enable named quantity checking we con-
sider a dimensionally correct assignment of
nt := 2 * addtq(t1,t2) with differing named
quantity definitions. In the first case we consider
t1 and t2 to both represent torque values, so
that environment τ is {nt 7→ Named "T", t1 7→
Named "T",t2 7→ Named "T"}. We also de-
fine addtq to expect two torque quantities. It
will be stored in the function environment σ as
{addtq 7→ ((x,Named "T"), (y,Named "T"),x+y)}.
The code fragment would look like this:
begin
nt : float of Named T;
t1 : float of Named T;
t2 : float of Named T;
fun addtq (x:Named T,y:Named T) = x+y
...
nt := 2 * addtq(t1,t2)
end
Quantity checking would succeed as shown in
Figure 5.
Alternatively, if we try a similar assignment,
nt := 2 * addtq(t,w), but with quantities denot-
ing torque and work:
begin
nt : float of Named T;
t : float of Named T;
w : float of Named W;
fun addtq (x:Named T,y:Named T) = x+y
...
nt := 2 * addtq(t,w)
end
Such that τ
0
= {nt 7→ Named "T",t 7→
Named "T",w 7→ Named "W"} then the proof
cannot be completed as the parameter w has the
named quantity Named "W" where a Named "T" was
expected, as shown in Figure 6. Thus the function
call cannot succeed and we would not compile this
programme.
Having to explicitly name each parameter quan-
tity is cumbersome and minimises reusability as many
functions would have to be duplicated. We can use
Noname quantities to avoid having to commit to a
given name, such as torque or work:
begin
nt : float of Named T;
t : float of Named T;
w : float of Named W;
fun addtq (x:Noname,y:Noname) = x+y
MODELSWARD 2022 - 10th International Conference on Model-Driven Engineering and Software Development
110
τ ` uexp
nexp
Named n τ uv = Named n
huv := uexp, τi
nstmt
(τ, Succeed)
[Valid Assign Stmt]
τ ` uexp
nexp
Named n
1
τ uv = Named n
2
n
1
6= n
2
huv := uexp, τi
nstmt
(τ, Fail)
[Fail Assign Stmt]
τ ` uexp
nexp
Noname τ uv = Named n
huv := uexp, τi
nstmt
(τ, Succeed)
[Valid Assign Stmt]
τ ` uexp
nexp
Noname τ uv = Noname
huv := uexp, τi
nstmt
(τ, Succeed)
[Valid Assign Stmt]
τ ` uexp
nexp
Named n τ uv = Noname
huv := uexp, τi
nstmt
(τ {uv 7→ Named n}, Succeed)
[Valid Assign Stmt]
hstmt
1
, τi
stmt
(τ
1
, Succeed) hstmt
2
, τ
1
i
stmt
(τ
2
, Succeed)
hif bexp then stmt
1
else stmt
2
, τi
stmt
(τ
2
, Succeed)
[Valid Cond Stmt]
Figure 3: Named quantity rules for assignments and conditionals.
σ,τ ` uexp
nexp
Named n
σ,τ ` huexp,Named ni
nparam
Named n
[Name Scaler Param]
σ,τ ` uexp
nexp
Noname
σ,τ ` huexp,Named ni
nparam
Named n
[Name Scaler Param]
σ,τ ` uexp
nexp
Noname
σ,τ ` huexp,Nonamei
nparam
Noname
[Name Scaler Param]
σ,τ ` uexp
nexp
Named n
σ,τ ` huexp,Nonamei
nparam
Named n
[Name Scaler Param]
hfun ufn(uv
1
:qn
1
,.. .,uv
m
:qn
m
) is uexp, σi
nfun
σ {ufn 7→ ((uv
1
,qn
1
),.. .,(uv
m
,qn
m
),uexp)} [Quant FDef]
σ ufn = ((uv
1
,qn
1
),.. .,(uv
m
,qn
m
),uexp)
σ,τ ` huexp
1
,qn
1
i
nparam
uqn
1
··· σ,τ ` huexp
m
,qn
m
i
nparam
uqn
m
σ,{uv
1
7→ uqn
1
,.. .,uv
m
7→ uqn
m
} ` uexp
nexp
qn
out
σ,τ ` ufn(uexp
1
,.. .,uexp
m
)
nexp
qn
out
[Quant FCall]
Figure 4: Quantity Checking rules for Function Declarations and Invocation.
...
nt := 2 * addtq(t,w)
end
In this case our function addtq ac-
cepts Noname quantities so σ
0
= {addtq 7→
((x,Noname),(y, Noname),x+y)}. However, the
function body will fail as both arguments to x+y need
to follow the named quantity rules for addition, as
shown in Figure 7:
Explicitly named quantity parameters protect the
function body but do not allow commonalities to
be exploited. Extending named quantities to in-
clude named quantity variables, Quantvar, so that
we could write generic quantity functions is recom-
mendable:
fun add (x:Quantvar q,y:Quantvar q) = x+y
In this case the variable q could be assigned to any
named quantity but both x and y would have the same
named quantity. Our function invocation rule would
need to be extended to ensure named quantity vari-
ables were uniquely assigned, and the named quan-
tity of each argument that shared the same quantity
variable were equal.
Discerning Quantities from Units of Measurement
111
4.3 Discussion
Our algebra of named quantities is intended to be im-
plemented as part of the static analysis phase of a
compiler for an existing programming language or
scientific domain specific language. Incorporating
named quantities into software models would expand
their use, and increase the robustness of designs. Al-
though named quantity and dimension analysis are
effective at discovering errors early, there are three
concerns that impede their adoption (McKeever et al.,
2020).
Lack of Awareness: many developers are totally
unaware of software solutions that deal with quan-
tities and UoM. Inertia arises from factors like
tradition, fear of change and effort of learning
something new. Our approach is intended for
language extensions or a pluggable type system,
but could equally be included in popular UoM li-
braries, both of which elicit change and adapta-
tion.
Technical Internal Factors: many solutions are
awkward and imprecise, introducing a loss of pre-
cision and struggling at times with dimensional
consistencies. The strength of a language based
solution, versus a library one, is that these issues
are reduced.
External Factors: modern systems are not built in
a vacuum but form part of an eco-system (Lungu,
2008). It is harder to argue for quantity annota-
tions when values pass through numerous generic
components that do not support them, such as
legacy systems, databases, spreadsheets, graph-
ics tools and many other components that are un-
likely to support quantities without costly updates.
However, efforts are underway to address this es-
sential issue (CODATA, 2021).
A lightweight and comprehensive language solu-
tion is fundamental to adoption. However, a rel-
evant observation from both a survey of UoM li-
braries (Bennich-Bj
¨
orkman and McKeever, 2018) and
interviews with practitioners (Salah and McKeever,
2020) was the need for quantities to be available at
run-time. There are many mature and active UoM li-
braries for popular dynamic object oriented program-
ming languages, such as Python and Ruby, in which
no static checking will occur. If we allow dimensions
to be only available at run-time then quantity check-
ing, and also unit conversion, will have to be under-
taken while the programme is executing. Faults can
be avoided but testing is required to ensure annota-
tions are congruent, a feature that a static programme
analysis will uncover prior to evaluation.
5 CONCLUSION
We have developed a simple algebra of named quan-
tities and shown how it can be incorporated into an
existing programming language. Thereby ensuring
quantities that share the same units of measure are
handled separately, if required. Our algebra is safe
and allows a degree of flexibility through casting up-
wards from unnamed quantities to named ones, thus
enabling greater code reuse and a more practical im-
plementation of the concept. Unnamed quantities can
be assigned to named one’s but not the other way
around as this breaks substitutability and potentially
reproducibility of experimental results. The algebra
is distinct to that of dimension checking but they can
be combined to form a single pass validator, allowing
aliases such as J for work or N for force to be part of
a prelude.
We lack an unqualified estimate of how frequently
unit inconsistencies occur or their cost. Anecdotally
we can glean that it is not negligible from experi-
ments described in the literature (Cooper and McK-
eever, 2008; Antoniu et al., 2004; Ore et al., 2017a;
Ore et al., 2017b). These focus on checking exist-
ing scientific repositories and are not representative
of any quantity adhering software discipline. They
have been applied post-development whereas we are
seeking to support developers by ensuring their code
bases model their scientific domain.
Quantity checking, much like type checking, is
extremely useful when developing as errors are found
before any code is run. Data on existing systems that
have been extensively tested are less indicative of cod-
ing practices. However annotating all unit variables in
a programme is costly. Ore (Ore et al., 2018) found
subjects choose a correct UoM annotation only 51%
of the time and take an average of 136 seconds to
make a single correct annotation. This explains the
appeal of systems that try to lower the burden while
still ensuring coverage through unit type variables and
a solver (Kennedy, 1994; Jiang and Su, 2006; Hills M
et al., 2012; Xiang et al., 2020), or compromise cover-
age through a component based approach (Damevski,
2009; Ore et al., 2017a). A component based disci-
pline means that the consequences of local unit mis-
takes are underestimated. On the other hand, it allows
diverse teams to collaborate even if their domain spe-
cific environments or choice of quantity systems are
dissimilar.
If all quantity type variables are resolved by the
static checker then dimensional correctness can be
shown. A corpus of quantity errors, their program-
ming language and associated software systems is re-
quired to assess the significance of annotations and
MODELSWARD 2022 - 10th International Conference on Model-Driven Engineering and Software Development
112
the cost of developing without. We have no idea of
how much time is spent chasing incompatible quan-
tity assignments, dimension errors or incorrect unit
conversions. We do know that there are many rea-
sons for not adopting a quantity discipline based ap-
proach (Salah and McKeever, 2020). Different stake-
holders will have different robustness concerns and
willingness to compromise on the proportion of quan-
tity and unit annotations required. Addressing usabil-
ity concerns is an important aspect of our research.
Our tool currently performs static named quantity
and dimension analysis for a simple imperative lan-
guage. It also searches for the least number of unit
conversions to reduce round-off errors in generated
code. Current work is looking at delaying conver-
sions when calling functions, along with quantity and
dimension variables that alleviate the annotation bur-
den, while increasing reusability, and allowing errors
to be discovered earlier in the code.
REFERENCES
Antoniu, T., Steckler, P. A., Krishnamurthi, S., Neuwirth,
E., and Felleisen, M. (2004). Validating the unit cor-
rectness of spreadsheet programs. In Proceedings
of Software Engineering, ICSE ’04, pages 439–448,
Washington, DC, USA. IEEE Computer Society.
Apple (2020). Swift open source. Online https://swift.org.
Last Accessed on 15th April 2020.
Bennich-Bj
¨
orkman, O. and McKeever, S. (2018). The next
700 Unit of Measurement Checkers. In Proceedings
of Software Language Engineering, SLE 2018, page
121–132, NY, USA. Association for Computing Ma-
chinery.
Bureau International des Poids et Mesures (2019). SI
Brochure: The International System of Units (SI),
9th Edition, Dimensions of Quantities. Online
https://www.bipm.org. Last Accessed 15th April,
2020.
CODATA (2021). Digital representation of units of mea-
surement. Online https://codata.org/initiatives/task-
groups/drum/. Last Accessed 25th December 2021.
Cooper, J. and McKeever, S. (2008). A Model-Driven Ap-
proach to Automatic Conversion of Physical Units.
Software: Practice and Experience, 38(4):337–359.
Damevski, K. (2009). Expressing measurement units
in interfaces for scientific component software. In
Proceedings of Component-Based High Performance
Computing, CBHPC ’09, pages 13:1–13:8, NY, USA.
ACM.
Dieterichs Henning (2021). Units of Mea-
surement Validator for C#. Online
https://www.codeproject.com/Articles/413750/Units-
of-Measure-Validator-for-Csharp. Last Accessed on
25th Of October.
Dreiheller, A., Mohr, B., and Moerschbacher, M. (1986).
Programming pascal with physical units. SIGPLAN
Notes, 21(12):114–123.
Foster, M. P. (2013). Quantities, units and computing. Com-
put. Stand. Interfaces, 35:529–535.
Fowler, M. (1997). Analysis Patterns: Reusable Objects
Models. Addison-Wesley Longman Publishing Co.,
Inc., Boston, MA, USA.
Gehani, N. (1977). Units of measure as a data attribute.
Computer Languages, 2(3):93 – 111.
Hall, B. D. (2020). Software for calculation with physical
quantities. In 2020 IEEE International Workshop on
Metrology for Industry 4.0 IoT, pages 458–463.
Hilfinger, P. N. (1988). An Ada Package for Dimen-
sional Analysis. ACM Trans. Program. Lang. Syst.,
10(2):189–203.
Hills M, Chen Feng, and Ros¸u Grigore (2012). A Rewriting
Logic Approach to Static Checking of Units of Mea-
surement in C. Electronic Notes in Theoretical Com-
puter Science, 290:51–67.
Jiang, L. and Su, Z. (2006). Osprey: A Practical Type Sys-
tem for Validating Dimensional Unit Correctness of
C Programs. In Proceedings of the 28th International
Conference on Software Engineering, ICSE ’06, pages
262–271, New York, NY, USA. ACM.
Joint Committee for Guides in Metrology (JCGM) (2012).
International Vocabulary of Metrology, Basic and
General Concepts and Associated Terms (VIM). On-
line https://www.bipm.org/en/about-us/. Last Ac-
cessed 15th April 2020.
Karr, M. and Loveman, D. B. (1978). Incorporation of
Units into Programming Languages. Commun. ACM,
21(5):385–391.
Kennedy, A. (1994). Dimension Types. In Sannella,
D., editor, Programming Languages and Systems—
ESOP’94, volume 788, pages 348–362, Edinburgh,
U.K. Springer.
Lungu, M. (2008). Towards reverse engineering software
ecosystems. In 2008 IEEE International Conference
on Software Maintenance, pages 428–431.
McKeever, S. (2021). From Quantities in Software Models
to Implementation. In Proceedings of the 9th Interna-
tional Conference on Model-Driven Engineering and
Software Development - MODELSWARD, pages 199–
206. INSTICC, SciTePress.
McKeever, S., Bennich-Bj
¨
orkman, O., and Salah, O.-A.
(2020). Unit of measurement libraries, their popular-
ity and suitability. Software: Practice and Experience.
McKeever, S., Pac¸aci, G., and Bennich-Bj
¨
orkman, O.
(2019). Quantity Checking through Unit of Measure-
ment Libraries, Current Status and Future Directions.
In Model-Driven Engineering and Software Develop-
ment, MODELSWARD.
Microsoft (2020). F# software foundation. Online
https://fsharp.org. Last Accessed on 15th April 2020.
NIST (2015). International System of
Units (SI): Base and Derived. Online
https://physics.nist.gov/cuu/Units/units.html. Last
Accessed October 2nd, 2019.
Discerning Quantities from Units of Measurement
113
Ore, J.-P., Detweiler, C., and Elbaum, S. (2017a).
Lightweight Detection of Physical Unit Inconsisten-
cies Without Program Annotations. In Proceedings
of International Symposium on Software Testing and
Analysis, ISSTA 2017, pages 341–351, NY, USA.
ACM.
Ore, J.-P., Elbaum, S., and Detweiler, C. (2017b). Dimen-
sional inconsistencies in code and ROS messages: A
study of 5.9m lines of code. In Intelligent Robots and
Systems, IROS, pages 712–718. IEEE.
Ore, J.-P., Elbaum, S., Detweiler, C., and Karkazis, L.
(2018). Assessing the Type Annotation Burden. In
Automated Software Engineering, ASE 2018, pages
190–201, NY, USA. ACM.
Salah, O.-A. and McKeever, S. (2020). Lack of Adop-
tion of Units of Measurement Libraries: Survey and
Anecdotes. In Proceedings of Software Engineering
in Practice, ICSE-SEIP ’20. ACM.
Sonin, A. A. (2001). The physical basis of dimensional
analysis. Technical report, Massachusetts Institute of
Technology.
Stephenson, A., LaPiana, L., Mulville, D., Peter Rutledge,
F. B., Folta, D., Dukeman, G., Sackheim, R., and
Norvig, P. (1999). Mars Climate Orbiter Mishap In-
vestigation Board Phase 1 Report. Last Accessed on
October 1st, 2019.
Witkin, R. (1983). Jet’s Fuel Ran Out After Metric Conver-
sion Errors. The New York Times.
Xiang, T., Luo, J. Y., and Dietl, W. (2020). Precise In-
ference of Expressive Units of Measurement Types.
Proc. ACM Program. Lang., 4(OOPSLA).
MODELSWARD 2022 - 10th International Conference on Model-Driven Engineering and Software Development
114
σ,τ ` t1
nexp
Named T
σ,τ ` ht1, Named Ti
nparam
Named T
σ,τ ` t2
nexp
Named T
σ,τ ` ht2, Named Ti
nparam
Named T
σ,{x 7→ . ..} ` x
nexp
Named T σ,{x 7→ . ..} ` y
nexp
Named T
σ,{x 7→ Named T,y 7→ Named T} ` x + y
nexp
Named T
σ,τ ` addtq(t1, t2)
nexp
Named T
σ,τ ` 2 addtq(t1,t2)
nexp
Named T τ nt = Named T
σ,τ ` nt := 2 addtq(t1,t2)
nexp
(τ,NameValid)
Figure 5: Successfully Quantity checking the addition of two torque values.
σ,τ
0
` t
nexp
Named T
σ,τ
0
` ht, Named Ti
nparam
Named T
σ,τ
0
w
nexp
Named W
σ,τ
0
` hw, Named Ti
nparam
...
σ,τ
0
` addtq(t,w)
nexp
...
σ,τ
0
` 2 addtq(t,w)
nexp
. . . τ
0
nt = Named T
σ,τ
0
` nt := 2 addtq(t,w)
nexp
...
Figure 6: Unsuccessfully Quantity checking a Function call with a torque value and a work value.
σ
0
,τ
0
` t
nexp
Named T
σ
0
,τ
0
` ht, Nonamei
nparam
Named T
σ
0
,τ
0
` w
nexp
Named W
σ
0
,τ
0
` hw, Nonamei
nparam
Named W
σ
0
,{x 7→ . ..} ` x
nexp
Named T σ
0
,{x 7→ . ..} ` y
nexp
Named W
σ
0
,{x 7→ Named T,y 7→ Named W} ` x + y
nexp
...
σ
0
,τ
0
` addtq(t,tw)
nexp
...
σ
0
,τ
0
` 2 addtq(t,w)
nexp
... τ
0
nt = Named T
σ
0
,τ
0
` nt := 2 addtq(t,w)
nexp
...
Figure 7: Unsuccessfully Quantity checking the addition of a torque value with a work value.
Discerning Quantities from Units of Measurement
115