I have updated dimensioned and it is much improved! Read about it here:

http://paholg.com/2017/03/03/dimensioned_0.6/

Feedback welcome!

I have updated dimensioned and it is much improved! Read about it here:

http://paholg.com/2017/03/03/dimensioned_0.6/

Feedback welcome!

2 Likes

Note for people like me:

"compile-time dimensional analysis" == "using types to represent measurement units (meters, seconds, ...)"

2 Likes

I don't understand what do you mean by "dimensional analysis", by I understand very well what is "using types to represent measurement units". Some years ago I wrote a C++ library to that purpose and I published it here: https://github.com/carlomilanesi/cpp-measures

You may be interested in looking at it.

In addition to represent units of measurement and their conversions, it represents absolute and relative measures, bi-dimensional and three-dimensional measures and transformations, and three different types of absolute angles.

For the context, dimensional analysis predates the modern concept of computers and is used to quickly check if given physical equation makes sense (if you've got mismatching dimensions, it probably has no meaning). In some sense it is a human-directed type system and it makes much sense to make it available to programming languages where possible

1 Like

Ah OK. But then I don't think a library doing only dimensional analysis is much useful. For example, it can check that if you divide miles by hours you get a speed, but usually you also have to distinguish hours from seconds, and optionally convert between them, you should distinguish absolute celsius degrees from relative celsius degrees, you should compute dot product and cross product between vector measures, you should apply linear or affine transformations in plane or in space, you should compute angles modulo one revolution. I wonder if that library does all that, or if there is another library that does that.

For example, it can check that if you divide miles by hours you get a speed, but usually you also have to distinguish hours from seconds, and optionally convert between them

This is covered in two different ways. Dimensioned works by defining a unit system and then working in that system, so all values are stored in terms of some combination of the base units. Say you're working in SI, there's a constant for hours, `HR`

. So, you can do:

```
let t = 5.0 * si::HR;
```

and `t`

will have type `Second<f64>`

and value `300.0`

. Say you want to print it in hours, you can do

```
println!("t: {} hr", t / si::HR);
```

Instead of `t / si::HR`

, you could do `*(t / si::HR)`

or `(t / si::HR).value()`

. Each of these extracts the value (as an `f64`

in this case), but they are only defined for dimensionless quantities, so it ensures that what you have is time.

Alternatively, you could create a unit system that has hours as a base unit, and convert between them using `std::convert::From`

and `Into`

, but this requires more setup.

you should distinguish absolute celsius degrees from relative celsius degrees

I have left this to a user. If one wants to work in celsius, then it would be easy enough for them to make `to_celsius()`

and `from_celsius()`

functions. Celsius isn't a real unit, so doesn't belong in a unit system.

you should compute dot product and cross product between vector measures, you should apply linear or affine transformations in plane or in space, you should compute angles modulo one revolution.

This is beyond the scope of dimensioned, and I think it should be. But there's no reason you can't use dimensioned with a linear algebra library. The idea is for it to act as a primitive replacer, but there are some caveats. I cover this in this fairly long example.

For example, this is how I define a cross product for a 3d vector:

```
pub trait Cross<Rhs = Self> {
type Output;
fn cross(self, rhs: Rhs) -> Self::Output;
}
impl<T, U> Cross<Vector3d<U>> for Vector3d<T>
where T: Mul<U> + Copy,
U: Copy,
Prod<T, U>: Sub<Output = Prod<T, U>>
{
type Output = Vector3d<Prod<T, U>>;
fn cross(self, rhs: Vector3d<U>) -> Self::Output {
Vector3d::new(self.y * rhs.z - self.z * rhs.y,
self.z * rhs.x - self.x * rhs.z,
self.x * rhs.y - self.y * rhs.x)
}
}
```

There is no reason that linear algebra libraries couldn't do this, but I think none that exist today provide this level of genericity (note that the parametrized types are allowed to be different and to change under multiplication). I plan to talk to linear algebra library authors and see how open they are to pull requests to this effect.

2 Likes