Unitless Distance (like Duration)?

I really like the new unitless Duration, I find it very intuitive to be able to write val time = 5.seconds (and not have to remember that it is really timeMs or timeNanos or whatever.)

Is there any hope of the same, but for distances?

I don’t think so. At least not in the standard library. Time is just much more common than distance. Maybe this could be done as a library. If people like it, it can always be added to the stdlib later.

Not sure what you’re looking for, but some time ago, someone presented a pretty cool library for unit management : Measured - Type-safe, intuitive units of measure

With that, you can write 5 * meters, for example.

1 Like

I took a look at Measured - I like the goal, but I think I’m greedy. :slight_smile:
I wish that Duration was based on a more open “Scalar value + unit of measure” pattern that could easily be extended.
Then we could have Distance, Angle, Mass, Temp, etc. and whichever other measurement systems people like (and some nice contributor could add 15.hands.inMeters)

1 Like

Hey @benjaminhill, I’m the author of Measured. I’d love to understand your use case to see why the library doesn’t cover it. There’s nothing preventing you from creating other unit types; the library is very extensible; and it actually uses “scalar + unit” model like you’re asking for.

// new units (like new types of Length) can be defined anywhere in your code
// Length is defined with meters as the base unit, so extensions to it
// need to indicate the conversion ratio to meters.
// According to Google, 1 hand == 0.1016 meter
val hands = Length("hands", 0.1016)

They can then be used just like the ones that ship w/ the library.

val length1 = 5 * hands
val length2 = length1 `as` meters // convert to Measure with new unit

// length1 `in` meters -> returns the scalar portion of the Measure
println("$length1 == $length2 or ${length1 `in` meters}")

You can also create new units by simply extending the Units class.

The library also already has many of the units you’re looking for: Distance (alias for Length), Angle, and Mass.

1 Like

Is there a word for the shock and appreciation you feel when the author of a library shows up in a discussion thread? :slight_smile:

I’ll be honest: I didn’t dig in too far into Measured because the signature is different than Duration. eg 5 * hands vs. 5.hands

The “times” is throwing me off, I worry that I’d write it the wrong way, then have to refactor later to fit with what seems to be the new Kotlin standard of “number-dot-unittype”

If Measured use the same signatures as Distance, (x.unittypes, y.inUnitTypes) I’d be all about it!

2 Likes

Thanks for sharing the feedback on this. It helps to understand what makes the library harder to pick up.

There are two reasons for using the 5 * hands notation:

  1. It allows more natural support for unit arithmetics and composition.
  2. It better represents the model of how scientific units work.

That said, a drawback to this approach (aside from difference w/ the standard lib) is that IDE autocomplete isn’t well supported. But this is something the Kotlin team could help with down the road.

On the first point, Measured lets you compose units in a natural way using * and / operations. This means you can write things like this w/o needing any new units:

val marathon              = 26 * miles
val velocity              = 3 * kilometers / hours
val timeToRunHalfMarathon = (marathon / 2) / velocity // 6.973824 hr

So 5 * hours is just as valid as 5 / hours. The latter naturally expresses a magnitude over a unit.

This also avoids complexity when trying to express compound units with x.unittypes scheme. That approach requires a new declaration for each permutation of the units. And it does not allow composition like Measured supports.

But, the great thing about Kotlin is you always create extension variables if you do want something like:

var Number.hands get() = this * hands_unit
2 Likes

Oh. OHHHHH. That makes total sense - especially your velocity example.

Do you support maven?

The library is in Maven Central, if that’s what you’re asking. Otherwise, you should be able to include it in your Maven-built project just fine; though I only use Gradle.