I discovered the existence of this in F# just recently, and wondered how I could get it in Kotlin.
I considered using a design like
Measure<Unit> myself, but had issues with it after I tried to use it in something more complex. If you use large arrays/lists of values with units, you have to choose between two equally bad options - either store them as primitives and wrap them when the caller asks for one element, or store them as wrappers and take the extra memory hit. Either option eats into computation time, and in my ray tracer, the cost/benefit trade-off wasn’t too appealing.
The nice thing about how this works in F# is that, at runtime, the values are just primitives, so it shouldn’t perform any worse than an array of primitives with no unit information. And in the case of JVM at least, the vector API (still in incubation) is convenient only when working with primitive arrays (or perhaps buffers? I haven’t investigated) - if you have wrappers then you have to copy the values out into an array before passing them off, and the extra copying is enough overhead that it almost defeats the purpose of using the vector ops. (I know, because I used to store my doubles in an
ImmutableList<Double>, and switched to a custom
ImmutableDoubleArray for this exact reason.)
Anyway, you would think that inline classes would be one way to remove that overhead, sort of like how Compose’s
I use a similar strategy for my
Angle class because it was way too easy to screw up the units of angles when dealing with trigonometry.
8.radians both return an
Angle which internally is always just storing radians, and then I just have my own version of all the trig functions… that worked cleanly - until I wanted to store a
Complex for an angle instead of a
Double. I haven’t introduced
ComplexAngle yet but it might happen… it won’t appear in public API so it isn’t as important.
The problem with trying to do inline classes for all types of measurement is that you then have expressions like
10.m / 5.s which has to return 2 m/s somehow… so you end up with a million little inline classes for all possible combinations and all the methods for the operators returning the right inline class for the resulting units. And eventually, someone hits a combination which there is no class for yet, because nobody imagined someone would want something like m/s³.
I don’t know if any library is trying to use inline classes for this yet - all the ones I’ve seen so far have been normal wrapper/data classes.
So I too think that type annotations are probably the way to go about this. I just have no idea how to implement that. Whatever it is, it would have to allow me to annotate
DoubleArray, and anything other custom class that might also be a container of doubles (like my own
Apologies for a bit of thread necromancy, but I thought it was better than creating a duplicate thread.