is a library to do dimension-aware calculations in C# and Java.
It offers numeric types that have dimensions, expressed in terms of base dimensions
M
(mass),
L
(length),
T
(time) and
Q
(electric charge). Playing to the strengths of each language, C# types have operator overloads to allow them to be used as numbers, while Java types mimic the BigDecimal with respect to arithmetic methods.
Dimenso offers compile-time support for dimension-aware calculations. Mismatch between dimensions is detected by the compiler, not at run-time. Modern IDEs will flag this mismatch even before compiling, and will offer to change the type of variables being assigned to, in order to match the resulting type of an expression. Attempting to create variables to hold intermediary results ("extract variable" refactoring) will tell you what is the type of the corresponding expression.
Consider the following code C# fragment (Java would have explicit calls to
multiply
and
divide
instead of literal multiplication and division operators):
mass m = new mass(3.5);
velocity v = new velocity(10);
force F = m * v;
This code fragment is not well-formed; mass by velocity does not result in force. One must either assign the result to the correctly-typed variable,
mass m = new mass(3.5);
velocity v = new velocity(10);
momentum p = m * v;
or rectify the calculation by using the rate of change of velocity in the multiplication:
mass m = new mass(3.5);
velocity v = new velocity(10);
acceleration g = v / new time(2);
force F = m * g;
My intention is to add some facilities to input and output values in different units, however, the
lingua franca
of Dimenso is the International System of Units (SI). Consequently, all number literals in the code fragment above correspond to magnitudes in the corresponding SI units for the quantities involved.
Types do not always have pretty names, like above, because not all combinations of dimensions have meaningful names, like momentum and force. However, the type's name will reflect the type's dimensions. For example,
mass m = new mass(3.5);
time t = new time(5.2);
m0k1s1a0 x = m * t;
That ugly type is just the product of mass and time, and outputting it will show its units to be
kg·s
.
I was always frustrated that, although my compiler ensured I did not accidentally multiply files by strings and then assign
them to exceptions, it treated all numbers the same.
The archetypal number-crunching language was Fortran, and since Fortran did exactly that, no language felt compelled to do otherwise.
In my mind, this defeats the purpose of strong typing. It is my belief that statically-typed languages deserve better, and Dimenso
is my approach of what I would like my language to give me out of the box: numerical types having physical dimensions, that can be
used to do calculations involving physical quantities.
The practice of eliminating dimensions and producing a calculation that deals with dimensionless numbers can be compared to
type erasure in Java. Like type erasure comes after compilation, where generics are statically checked,
and leaves a program working with raw types at run-time, this dimension erasure comes after checking the calculation by hand
and leaves a program with dimensionless numbers at compile-time.
Lately, I became aware of Fortress (see sidebar), an experimental language in the field of
scientific programming that does include support for dimensions and units.
Although the current implementation does not extend to these features yet, the
specification document is a very good read on the concept of working with
dimensions in a programming language.