Ability to mark types as value-type restricted

Eventually the JVM will get support for value types. Even though Valhalla is very early days we already have a fairly clear idea of what such types will look like:

  • No object identity, thus no identityEquals allowed.
  • No monitor, thus no await/notify/synchronised.
  • All fields must be final.
  • No finalisation allowed.
  • May not have virtual/open methods.
  • May not have fields of its own type.

Value types are, at heart, just an optimisation. Thus when the JVM finally supports value types and generics specialisation, any types that are compatible with the above restrictions could be optimised (ignoring binary compatibility, serialisation and other complicating factors here).

This leads to the thought that it’d be nice if the Kotlin compiler already had a notion of value types, such that by annotating a class as @ValueType the above restrictions were enforced: not allowed to synchronise on the type, all fields must be final, identityEquals is forbidden, may not refer to itself, etc. Violating these rules would perhaps be a compiler warning.

This would make it a whole lot easier to evolve write code now that nicely evolves into the future, because you can make a class that should be optimisable in future, and warn the developer that doing something like synchronising on it or breaking the other rules might result in code that fails in future. Potentially such an annotation could even define whether to be a warning or an error, like @Deprecated does.

Some classes that are currently in the stdlib could become candidates for such marking, for instance, Pair or Triple. Although some of the restrictions on value types may be too onerous for those (in particular the inability to recursively embed itself would prevent Pair<Pair<X, Y>, Z>, which is perhaps a questionable type, but I’m sure it crops up in real code.

I know that in my own code I define what should be value types quite frequently. It’d be nice if I could programmatically prevent my team from writing code that would break such a conversion.


The biggest thing missing from the list of restrictions is: such a type can not be passed as a generic type argument where T : kotlin.Any is expected. And integrating something like this into Kotlin is not exactly a trivial task, although I agree it would make sense to look into it

Is such thing can be handled automatically, like, with boxing?

Sometimes. Boxing is why I didn’t put “cannot be a nullable type” in the list, because you can have nullable value types via boxing, and Kotlin does.

But then, of course, you lose the benefits.

I second Mike’s request, when Kotlin supports value types, such standard annotation could be used to automatically refactor code into new syntax without all the hassle of revisiting codebase class by class.