Kotlin Shape Class

Could you please help, are any Youtrack issues for shape classes support? I’d like to extend existing or create new.

There are plans for it at the .Net Core - https://github.com/dotnet/csharplang/issues/164.

What features I expect:

  1. Ability to extend the existing companion objects or Java Static layer with statefull logic. For example, I’d like to have something like this:
shape object Duration { // <-- these methods will be attached to this class
      val MAX: Duration = Duration.ofHours(999); // e.g. we extend static members of class
} 

fun getTimeout(input: String): Duration {
    return when(input) {
          ...
         else -> Duration.MAX
    }
}
  1. Ability to omit companion objects in generic declaration
shape object Duration : Converable<Long, Duration> {
      override fun convert(from: Long): Duration = Duration.ofNanos(from)
} 

fun <TResult> fromLong(input: Long): TResult
  where TResult.Companion: Convertible<Long, TResult>  { // so Kotlin Compiler can attach necessary factory-like objects
      return TResult.convert(input) // we called method from shape class or from companion object
}

Your first example could be easily implemented by companion extensions:

val Duration.Companion.MAX get() = Duration.ofHours(999)

The second one is about contracts on Companions. It is not possible right now, but it was discussed multiple times. I call them companion interfaces. I can’t find one clear proposal right now, but there were several discussions here.

Duration class is from Java, it doesn’t have companion object.

And I pre-created value before, so right code сould be like this:

private val maxDuration = Duration.ofHours(999)

val Duration.Companion.MAX get() = maxDuration

For that you need KT-11968.Pre-created values should be stored externally, because otherwise it will produce a lot of problems with initialization order (there are already a lot of them).

1 Like

Interesting. However as I can see I couldn’t attach the interface implementation to existing Companion object.

Moreover, I have explicitly put the companion object into the methods like fun <TResult> fromLong(input: Long) above, however compiler can resolve them automatically.

Companion interfaces are very important for future. They could allow to solve most of HKT use-cases and are really useful for a lot of things including serialization. But they require careful design, study and discussion.

1 Like