benasher44/uuid

Class API must be compatible with Java UUID

Closed this issue · 7 comments

One of the promises of Kotlin is perfect Java interop. We have to uphold this promise if we want to be included in Kotlin’s STD. The java.util.UUID class has some functionality that nobody really needs, however, a subset of it is definitely relevant in general.

I would say that the following subset makes sense for a UUID class that supports multiple UUID versions:

expect class UUID(msb: Long, lsb: Long) : Comparable<UUID> {
    val mostSignificantBits: Long
    val leastSignificantBits: Long
    fun variant(): Int
    fun version(): Int
}

I chose expect in the above example on purpose because we have to define it as such in common. Otherwise we are not able to use actual typealias UUID = java.util.UUID in the JVM part of the library; which is required for perfect Java interoperability.

There are a few gotchas here but those should be resolved as part of the pull request.

Required for inclusion in Kotlin STD (see #25).

Is the requirement that the Jvm side has to use java.util.UUID, or can it use the native kotlin one? This impacts a few decisions, mostly around constructors and ByteArray:

  1. We have to stick to UUID(msb: Long, lsb: Long) as the primary constructor, and everything else will have to become free functions. We can't add more constructor requirements to that expect declaration (can't add them to jvm.util.UUID).
  2. Exposing ByteArray will be slow on JVM. Since we don't have access to an underlying ByteArray, it'll have to be an extension function there, which constructs it for every call.

I'd say yes, we have to but this is a question for JetBrains since they have the final word on it.

  1. We could define all constructors as freestanding. Some argue that this is better design anyways as it helps encapsulation and obviously is more functional.
  2. There's no way around this I fear.

Another thing that will bite us is the borked comparison of the Java implementation. Not sure if we have to implement this the same way everywhere but I guess we have to.

How is it borked?

🤦‍♂️ lets just implement correct compareTo for now?

We can do that with the non Java targets but the ultimate goal for Java is a actual typealias Uuid = java.util.UUID and with this we cannot change the existing Comparable implementation.

Fixed in #72