Working with the SI system in Java

The SI system and the relationship between units of physical quantities.

The SI system and the relationship between units of physical quantities.

Library for working with the SI unit KotUniL, originally developed in Kotlin, has recently been made multi-platform. In particular, it is now available in JavaScript, as described here.

Why is this library needed?

When programming in the traditional way, it is very easy to lose sight of the units in which the numbers we operate with are measured. For example, you can add meters to liters, and no compiler will help us with this.

This problem is real and has been proven to cause accidents costing many millions of dollars. (One of the stories is here).

This can be avoided by using special libraries that work correctly with physical units of the SI system such as meters or watts and other units such as currencies or pieces.

One of these libraries is KotUniL (si-units).

Use of technology Kotlin Multiplatform allows you to get code for a number of platforms from Kotlin code, including JVM.
This means that the functionality implemented in the library can be used from Java programs. (Strictly speaking, this could be achieved without using Kotlin Multiplatform, but in this case we get the JVM libraries automatically along with other options, which saves our efforts).

How to use it?

And how to use the library from Java?
You can connect the library to your project as a dependency:

repositories {
    mavenCentral()
}

dependencies {
    implementation("eu.sirotin.kotunil:kotunil-jvm:<version>")
}

At the time of writing, the latest version was 4.1.1

What are the differences between Kotlin and Java variants?

And then everything is the same as in Kotlin? Unfortunately, there are two important differences.

FirstlyJava does not support operator overloading and therefore the code looks less elegant than in Kotlin.

Consider, for example, the following problem: Masha was wiping the glass of the aquarium from the outside, touched a vase standing nearby, as a result of which the glass of the aquarium broke and water leaked onto the floor. The aquarium before this trouble was 32 liters of water. Masha’s room is 4 meters long and 4.3 meters wide. At what height in mm. is there water in the room now, assuming it stayed there and didn’t leak out?

In Kotlin, the solution looks like this:

val s = 4.m * 4.3.m
val h = 32.l/s 

And in Java, instead of the signs of arithmetic operations on dimensional units, we have to use functions:

Expression s = m.times(4).times(m.times(4.3));
Expression v = L.times(32);
Expression h = v.div(s)

However, all other charms of KotUniL are preserved. You can’t add amps to seconds, but you can multiply and divide.

Secondly, transforming the Kotlin code into Java code, the transpiler creates two Java classes for the library classes from one Kotlin class. Therefore, for example, when working with meters, we must add the following line to Java imports:

import static eu.sirotin.kotunil.base.MetreKt.*;

You can provide further information about KotUniL in the repository on GitHub (see a detailed example of working with SI units in Java in the module app/jvm/java-console).

You can read about the theoretical foundations and features of using KotUniL in this series of flocks:

  1. The magic of dimensions and the magic of Kotlin. Part One: Introduction to KotUniL

  2. The magic of dimensions and the magic of Kotlin. Part Two: Advanced Features of KotUniL

  3. The magic of dimensions and the magic of Kotlin. Part Three: Mixing Magic

Are there any alternatives?

I developed KotUniL because none of the libraries that existed at that time satisfied me. In the Java community there is JSR 385. Obviously, the developers of this specification had similar motivations to mine. But there, the developers took the path of highlighting dimensions. They got Quantity<Volume>, Unit<Length> and so on. Of course, all possible combinations cannot be covered in this way, but many applications will not have to do this.

Here article on Baeldung about the general view of working with the library.

I didn’t like the design of the library. What is a similar example of converting meters to kilometers worth, taken by me from the article recommended above!:

double distanceInMeters = 50.0;
UnitConverter metreToKilometre = METRE.getConverterTo(MetricPrefix.KILO(METRE));
double distanceInKilometers = metreToKilometre.convert(distanceInMeters );

Using KotUniL you write it like this:

val d = 50.m
val x = d.km

I understand that the advantage of JSR 385 lies in the detection of typing errors at compile time, and not in the visibility of code brevity. In this article, I show that any KotUniL formulas are checked for typing errors with exactly one unit test with code clarity similar to that of technical and scientific articles.

Why is the SI standard not implemented in Kotlin?

So, in the Java world, there is at least the JSR 385 specification regarding the implementation of handling SI units, but how is this in Kotlin?

Unfortunately, there is no such library among the existing and developed Kotlin standard libraries.
I suggested that the language developers include this functionality (not necessarily KotUniL) in the libraries that come with the language: (KT-55556). But he hasn’t convinced them yet. But it is possible, if you, dear readers, actively support this proposal (and at the same time KotUniL on GitHub :-), then the situation will improve.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *