# Measured - Type-safe, intuitive units of measure

**URL:** <https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094>\
**Category:** Libraries\
**Created:** [June 16, 2020, 12:10am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094 "2020-06-16T00:10:59Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![joe\_bloggs](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/joe_bloggs/32/7668_2.png) [@joe\_bloggs](https://discuss.kotlinlang.org/u/joe_bloggs)\
**Post date:** [June 16, 2020, 12:10am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/1 "2020-06-16T00:10:59Z")

</div>

I recently released [Measured](https://nacular.github.io/measured/). A library that makes units a lot simpler and intuitive to work with. It uses the compiler to enforce correctness and lets you combine units into more complex ones using math operators. It is also extensible, making it easy to define your own units.

```auto
val velocity = 5 * meters / seconds
val acceleration = 9 * meters / (seconds * seconds)
val time = 1 * minutes

// d = vt + ½at²
val distance = velocity * time + 1.0/2 * acceleration * time * time

println(distance ) // 16500 m
println(distance `as` kilometers) // 16.5 km
println(distance `as` miles ) // 10.25262467191601 mi

println(5 * miles / hours `as` meters / seconds) // 2.2352 m/s

```

Give it a try. I’d appreciate any feedback.

---

<div class="post-metadata">

**Author:** ![crummy](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/crummy/32/7034_2.png) [@crummy](https://discuss.kotlinlang.org/u/crummy)\
**Post date:** [June 22, 2020, 4:27am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/2 "2020-06-22T04:27:08Z")

</div>

Very cool! Could you explicitly declare the types for e.g. velocity, acceleration, and time in your example to be a little clearer on how it works?

---

<div class="post-metadata">

**Author:** ![joe\_bloggs](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/joe_bloggs/32/7668_2.png) [@joe\_bloggs](https://discuss.kotlinlang.org/u/joe_bloggs)\
**Post date:** [June 22, 2020, 11:21pm UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/3 "2020-06-22T23:21:00Z")

</div>

This is what it looks like with explicit types.

```auto
val velocity: Measure<UnitsRatio<Length, Time>> = 5 * meters / seconds
val acceleration: Measure<UnitsRatio<Length, UnitsProduct<Time, Time>>> = 9 * meters / (seconds * seconds)
val time: Measure<Time> = 1 * minutes

// d = vt + ½at²
val distance: Measure<Length> = velocity * time + 1.0/2 * acceleration * time * time

println(distance ) // 16500 m
println(distance `as` kilometers) // 16.5 km
println(distance `as` miles ) // 10.25262467191601 mi

```

The library also has typealiases for Velocity and Acceleration; so you could simplify it as follows:

```auto
val velocity: Measure<Velocity> = 5 * meters / seconds
val acceleration: Measure<Acceleration> = 9 * meters / (seconds * seconds)
val time: Measure<Time> = 1 * minutes

// d = vt + ½at²
val distance: Measure<Length> = velocity * time + 1.0/2 * acceleration * time * time

println(distance ) // 16500 m
println(distance `as` kilometers) // 16.5 km
println(distance `as` miles ) // 10.25262467191601 mi

```

---

<div class="post-metadata">

**Author:** ![crummy](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/crummy/32/7034_2.png) [@crummy](https://discuss.kotlinlang.org/u/crummy)\
**Post date:** [June 22, 2020, 11:45pm UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/4 "2020-06-22T23:45:32Z")

</div>

I tried to do something similar in Java for a project a while back for distances and velocity but it was … verbose to say the least. This is really nice, wish I had a project I needed it for!

---

<div class="post-metadata">

**Author:** ![joe\_bloggs](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/joe_bloggs/32/7668_2.png) [@joe\_bloggs](https://discuss.kotlinlang.org/u/joe_bloggs)\
**Post date:** [June 23, 2020, 1:53am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/5 "2020-06-23T01:53:28Z")

</div>

I’ve also found it valuable when working with simple units like time (see [Doodle](https://nacular.github.io/doodle/)). It is much safer than relying on conventions: like all times are in milliseconds.

---

<div class="post-metadata">

**Author:** ![medium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/medium/32/10404_2.png) [@medium](https://discuss.kotlinlang.org/u/medium)\
**Post date:** [June 23, 2020, 6:18am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/6 "2020-06-23T06:18:05Z")

</div>

Plus: you can enforce some constraints directly when the object is created. If you had for example a `Length` object you would likely exclude negative length. In my current project we are using little classes for almost everything and it really pays off. It is not only clear what exactly this String, Int or whatever means, but the type is also enforcing and documenting the rules.

Example:

```auto
data class VehicleCode(val value: String) {
  init {
    require(value.length == 20) { "Value must have 20 characters." }
    require(value[7] == '-') { "Value must have '-' at position 8." }
  }
}

```

Since creating such classes is so easy in Kotlin, I think this should become a common best-practice in Kotlin. And libraries like “Measured” make it even easier!

---

<div class="post-metadata">

**Author:** ![clovisai](https://avatars.discourse-cdn.com/v4/letter/c/a9adbd/32.png) [@clovisai](https://discuss.kotlinlang.org/u/clovisai)\
**Post date:** [June 26, 2020, 10:08am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/7 "2020-06-26T10:08:58Z")

</div>

You should read into Kotlin Arrow Meta’s refinement types. It adds a specific syntax for these with nice behavior (as in, the compiler can automatically cast from an Int to a VehicleCode if the requirements are satisfied, etc)

---

<div class="post-metadata">

**Author:** ![lamba92](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lamba92/32/5089_2.png) [@lamba92](https://discuss.kotlinlang.org/u/lamba92)\
**Post date:** [June 26, 2020, 10:44am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/8 "2020-06-26T10:44:59Z")

</div>

I would recommend to be consistent with the Kotlin standard library for type conversion!

The stdlib uses extension functions like `Duration.toLongMilliseconds(): Long` or `Int.toLong()`. It is more tedious for the library developer to cover all cases, but is far more intuitive to use as library consumer since the IDE can easily hint what you need!

Btw your lib is awesome 🙂 keep it up!

---

<div class="post-metadata">

**Author:** ![astronaut4449](https://avatars.discourse-cdn.com/v4/letter/a/d2c977/32.png) [@astronaut4449](https://discuss.kotlinlang.org/u/astronaut4449)\
**Post date:** [June 30, 2020, 7:52am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/9 "2020-06-30T07:52:57Z")

</div>

I highly discourage the us of `as`.  
Either use a convert function or use the “in” operator.

```auto
distance = 3 kilometers
distance in meters

velocity = 3 meters / second
velocity in (kilometers / hour)

```

---

<div class="post-metadata">

**Author:** ![joe\_bloggs](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/joe_bloggs/32/7668_2.png) [@joe\_bloggs](https://discuss.kotlinlang.org/u/joe_bloggs)\
**Post date:** [June 30, 2020, 8:10am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/10 "2020-06-30T08:10:20Z")

</div>

I’d love to find a better pair of conversion method names. How would you use `in`? It maps to `fun contains(...): Boolean`. So I don’t see how it can work for conversion.

---

<div class="post-metadata">

**Author:** ![astronaut4449](https://avatars.discourse-cdn.com/v4/letter/a/d2c977/32.png) [@astronaut4449](https://discuss.kotlinlang.org/u/astronaut4449)\
**Post date:** [June 30, 2020, 8:16am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/11 "2020-06-30T08:16:00Z")

</div>

> [@joe\_bloggs](#):
>
> So I don’t see how it can work for conversio

You are right 😃  
`in` with backticks would still be better than `as` I would say.  
What’s wrong about an infix function named `convertTo`?

---

<div class="post-metadata">

**Author:** ![joe\_bloggs](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/joe_bloggs/32/7668_2.png) [@joe\_bloggs](https://discuss.kotlinlang.org/u/joe_bloggs)\
**Post date:** [June 30, 2020, 8:48am UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/12 "2020-06-30T08:48:38Z")

</div>

There are two methods: `in` and `as`. Both use back ticks. The `in` method coverts a `Measure` to a number instead of another `Measure`:

```
distance `as` kilometers // 16.5 km
distance `in` kilometers // 16.5

```

Most code will use `in` as the terminal point for a `Measure`. Or when passing one to code that uses raw numbers. The use of `as` should be less common, and likely pertain to displaying values like in the doc examples.

---

<div class="post-metadata">

**Author:** ![gidds](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/gidds/32/10865_2.png) [@gidds](https://discuss.kotlinlang.org/u/gidds)\
**Post date:** [June 30, 2020, 3:56pm UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/14 "2020-06-30T15:56:58Z")

</div>

There’s already a perfectly good standard for conversion functions: `.toXxx()`. Everything else uses it; it’s universally understood, very clear, and reads well.

So why does this project do something different, something that (judging from this thread) causes some confusion, as well as awkward syntax (backticks)? Why is this any different from converting a Long to an Int, a List to a Set, or a DateTime to an Instant?

IMHO, infix functions and operator overloads are best used sparingly, only where there’s a clear reason not to do things the ordinary way, where the intent is crystal clear and matches any existing usage. This doesn’t seem to be one of those situations.

`as` seems a particularly bad choice, as it usually means something different: `.asXxx()` functions create a _view_ of an existing object, one which reflects changes to that object (and whose changes are applied back to it). Your use _looks_ like that, but behaves differently, which could lead to subtle bugs.

---

<div class="post-metadata">

**Author:** ![joe\_bloggs](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/joe_bloggs/32/7668_2.png) [@joe\_bloggs](https://discuss.kotlinlang.org/u/joe_bloggs)\
**Post date:** [June 30, 2020, 7:25pm UTC](https://discuss.kotlinlang.org/t/measured-type-safe-intuitive-units-of-measure/18094/15 "2020-06-30T19:25:39Z")

</div>

Unfortunately the `toXxx()` convention doesn’t work well for this problem. Units are not a small, closed set that translate well to a set of functions. That means you’d have an explosion of very specialized functions to cover the wide range of units. Not to mention complex units like Newtons. Moreover, Units like Newton can be represented by a wide range of combinations. So the typealias for it would be something like:

`typealias Newtons = UnitsRatio<UnitsProduct<Mass, Length>, UnitsProduct<Time, Time>>`

And conversions would need to support any way of representing a Newton, say: `kilograms * miles / (hours * minutes)`. This is a big reason why the framework does not provide specialized conversion methods.

Also, notice that the `as` and `in` methods take instances of `Units` and not the class itself. Saying `value 'as' Newton` does not make sense because you can’t convert between Unit types, only between unit instances. So `Newton` here is a type, but there are many ways to represent it that do not require new classes.

Bespoke conversions are not defined in the framework because of these differences. You can always add them for specific `Measure<T>`s as extension methods if you have a set that are particularly important for your use-case. But I’m not sure how much easier, or readable that is vs the current approach.
