SciProgCentre/kmath

Non type-safe units

Opened this issue · 11 comments

(unit = "m", value = 42.0) / (unit = "s", value = 2.0) = (unit = ("/", "m", "s"), value = 21.0)

Values with a unit can be implemented as pair of MST of the special context and unit.

Possible benefits: valid unit shape, concise implementation.
Possible problem: lack of simplification of the shape.

MST-based units require additional considerations. On one hand, they are not compile-time type-safe, so they do not make sense in this regard. On the other hand, the context used to generate those units could provide runtime type unit check. Also with a staged compilation like one available in jupyter, it could be beneficial.

I think the main problem is that N*m ≠ m*N etc.

MST does not state that binary operation should be commutative. On the contrary, I would not expect that.

I mean units are not simplified to a certain comparable form

However, it is not such hard to implement such an algorithm - it is much easier than simplify a plain expression.

Did the Measured lib prove useful? This was discussed as a possible path in #75.

This issue is not about user level api. It is about generalization of symbolic processing of units. Measured is a nice way to use units and we do not want to dublicate it.

I've reworked the prototype without MST - units are stored as a product of base units.

import space.kscience.kmath.operations.RealField
import space.kscience.kmath.units.*

public fun main() {
    var res = with(MeasurementExtendedField(RealField)) {
        val a = (2.0 * kg) / (3.0 * m) / (2.0 * with(MeasureAlgebra) { s * s })
        val b = (23.0 * Pa)
        a + b
    }

    println(res)

    res = with(MeasurementExtendedField(RealField)) {
        val a = (2.0 * G(m)) + (3.0 * M(m))
        val b = (3.0 * au)
        a + b
    }

    println(res)
}
Measurement(measure=Measure(chain={SECOND=-2, METER=-1, KILOGRAM=1}, multiplier=1.0), value=23.333333333333332)
Measurement(measure=Measure(chain={METER=1}, multiplier=1.0), value=4.507966121E11)

Process finished with exit code 0

Actually, it is a dynamic analogue of Measured API.