Date: 2001-04-12 16:09:57
I heartily agree with the need for a workable solution to this
problem. I have been carrying this issue for over 20 years now, and
have found, in C++, the first programming language that makes it
feasible to solve.
With all due respect to the OP, the problem is far, far subtler than
seems at first glance. The usual nomenclature is this area is that of
"commensuration"; the central issue is whether two given values can be
meaningfully combined via a given operator. It is not likely, for
example, to find much meaning in summing Avogadro's number with the
speed of light. On the other hand, their product can be meaningful in
the right context.
There are recognized international standards involved, too. The
International System of Units (generally abbreviated SI) is authorized
via the Convention of the Metre, a diplomatic treaty to which many
countries are signatories, and hence has the force of law, as I
understand it. (See, for example, http://www.bipm.fr) It is via my
study of SI that I have come to certain realizations that, I believe,
apply to computation with attached units.
Chief among these realizations is that it is important to distinguish
between measurable quantities (e.g., mass, length, temperature, energy)
and the units in which they can be measured (e.g., kg, m, K, J).
Accordingly, I would argue there is an error in one of the OP's
examples: it is indeed meaningful to sum two values, one given in
meters and the other in feet, because both are length quantities and
hence commensurate for purposes of addition. Such an expression ought
therefore not give rise to a compile-time error, in my opinion.
In my opinion, it is the measurable quantities that most closely
correspond to the notion of types in the programming language sense.
The units in which we measure these quantities are merely (somewhat
arbitrary) constants that have been selected by convention. To quote
Lynn Arthur Steen,
"Numbers became really useful only after the French introduced the
metric system in an attempt -- still not fully successful -- to
overcome computational complexity and regional units of measure."
(BTW, a largely unknown and unrecognized provision of the Magna Carta,
signed in 1215, made an early attempt at the standardization of certain
units of measure:
"Throughout the kingdom there shall be standard measures of wine,
ale, and corn. Also there shall be a standard width of dyed cloth,
russet, and haberject.... Weights [also] are to be standardized
To complicate matters, different applications of commensuration have
different concepts of what quantities are commensurate. As one
example, is is common in high-energy physics to carry out calculations
in which the speed of light is taken to be one -- yes, just one, with
no units attached. A consequence of this is that length and time
become commensurate: length becomes measured in (fractions of)
light-seconds, the time it takes light to travel a certain distance.
Then there are such mundane, yet important, topics as I/O of such
values. It does little good to attach units while computing, yet lose
them on output. And if one can output them, one ought be able to read
them back in.
Because many units are based on constants of nature, those become
issues, too. The CODATA Internationally recommended values of the
fundamental physical constants are available, for example, at
I have developed a library, SIunits, that takes all of this (and more)
into account. Via SIunits, one can compute with meters per second just
as easily as with furlongs per fortnight -- and treat them as
commensurate values, because they are both measures of velocity.
My employer made my earliest version of SIunits, dating from 1998,
publicly available. Under active development (and assuming I can get a
summer student to work with me), I hope to have an even more
comprehensive version available in a few more months. This will be
version 8, and will rely heavily on modern metaprogramming concepts.
Assuming there might be interest among the Boost community, I have
sought preliminary approval to contribute the modern SIunits to Boost.
If a meeting of Boosters is planned for Copenhagen, this topic might be
worth a few minutes of discussion there.
Dejan Jelovic <djelovic_at_[hidden]> wrote on Thu Apr 12 13:54:42 2001:
| On September 23, 1999, NASA lost the Mars Climate Orbiter just as it was
| starting to circle the planet. The cause was a failure to convert
| navigational data from the English units used by one group of technicians to
| the metric units used by another.
| In order to avoid problems like this in my programs, I've developed a
| template class called arithmetic_type_wrapper. It provides a thin wrapper
| around primitive types like int and double but lets you define different
| types to represent different things.
| For example, say you have to do some calculation in meters and feet and want
| to represent different units with different types. The code for something
| like that would be:
| class meters_tag;
| typedef arithmetic_type_wrapper<double, meters_tag> meters;
| class feet_tag;
| typedef arithmetic_type_wrapper<double, feet_tag> feet;
| meters m = meters (10) + meters (20); //ok
| feet f = feet (5) + feet (10); // ok
| meters (10) + feet (20); // oops, compile-time error
| Is there any interest in adding this to Boost?
| P.S. I usually demonstrate this with apples and oranges, but then noone
| takes me seriously :).
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk