Has there been any discussion around inline classe...
# language-proposals
Has there been any discussion around inline classes and having them conform to a contract similar to enums? For example, it'd be nice to be able to generify over the ability to wrap/unwrap. With enums I can bound a generic on
: Enum<T>
which (combined with
) lets me do
T -> String
String -> T
conversion. It would be nice to achieve similar
T -> V
V -> T
conversions with an inline type (where
is the property type) in a generic way. Right now I'm using a factory where you have to pass
as arguments which leaves a lot to be desired.
👍 3
Out of curiosity, what's the use case? I can't think of much for the enum thing either.
Of course! 🤦‍♂️
in my case, a database where columns are fixed types (Long, String, Double, byte[]) but you want to use more meaningful types. We normally require you to write a full adapter with to/from methods but for Enums we can do it automatically. It would be nice to do the same for inline classes.
I wonder whether "an inline class can only have single property" is a permanent rule or something that is going to be "fixed" when the JVM actually gets value types though.
It's under "Current limitations" in the KEEP.
It wouldn't be inline in that case, it would be a value type
Well, you can define
and require users to implement the interface of they want automatic handling. The problem with this is that backing val will have to have same name.
Tell me if I'm missing something, but from what I understand the main thing preventing multiple properties is that functions can only have a single return value and constantly allocating temporary objects is too slow. That could then be solved with value types.
Yeah I was more thinking the compiler could make the companion implement a common interface with to/from conversion. Or perhaps there could be intrinsic top-level to/from functions and a marker supertype we could use in generic bounds.
I don’t think to/from conversions to a backing type are always something that should be allowed. If there is an interface/companion function, you can call it from the normal code.
Also a constructor can be private and instance created from the factory method in companion, or something.
I don’t mean it doesn’t make sense, I mean it needs design 🙂
(constructors for inline classes can't be private)
Ah, right. Sorry for confusion.
Also not sure it is important limitation, or just something that wasn’t designed yet.
First you disallow it, then you design it, then you win 🙂
That's about java interop, you can't force someone calling from Java to go trough the constructor.
Okay, I need to stop mumbling and go to bed 🙂
I believe Keep 87 may address some of these concerns
Copy code
/** new type **/
inline class Id(val value: String)

/** proof there is an isomorphism between [A] and [B] **/
interface Iso<A, B> {
  fun from(a: A): B
  fun to(b: B): A

/** proof [Id] <-> [String] **/
extension class IdStringIso : Iso<String, Id> {
  override fun from(a: String): Id = Id(a)
  override fun to(b: Id): String = b.value

/** For All [A] for which there is an isomorphic [B] provide a conversion function **/
fun <A, B> A.convert(with iso: Iso<A, B>): B =

/** This compiles because finds proof in `IdStringIso` **/
val id : Id = "000".convert()
👍 1
Iso is overly generic and the same can be modeled with a simple
To<A, B>
more constrained interface
The compiler will project the discovered instance that satisfies the type predicate and activate the extension syntax
you can even provide a
override that let's you destructure the conversion for all `A`s such as that:
Copy code
val (value) = id
val (id) = value
Having to write
at all is a loss for me. I already have an interface representing a converter and I'm trying to create a single implementation which can be used for any inline class (like I can do for enums)