Would there be any interest in providing a mechani...
# language-proposals
r
Would there be any interest in providing a mechanism to make a foreign type implement an interface?
I’m imagining a world where, given these two interfaces:
Copy code
interface A {
  val x: String
  val y: Int
}

interface B {
  val x: String
  val y: Int
  fun z(): Boolean
}
you could adapt any
A
to be a
B
using some terse syntax like this:
Copy code
type A : B {
  override fun z(): Boolean = x.toIntOrNull() == y
}
and the compiler could prove that an instance of
A
is now a
B
and can be used wherever a
B
is needed without needing to call a function to adapt it.
At the moment I find myself doing something like this, which is quite verbose and boiler platey:
Copy code
class AtoBAdapter(a: A): B {
  override val x: String = a.x
  override val y: Int = a.y
  override fun z(): Boolean = x.toIntOrNull() == y
}

fun A.asB() = AtoBAdapter(this)
and of course requires me to call
a.asB()
whenever I need to pass an
A
to something that needs a
B
.
s
Isnt that inline classes?
If you want to go beyond what inline classes offer then I am pretty sure that it cannot be done. Types are much more than a compile time thing and enforced at runtime on certain platforms like the jvm.
r
If it is, I don’t understand how. If I make my
AtoBAdapter
a
value class
then I still have to declare all the members which
B
shares with
A
, and I still have to call a function whenever I need to convert an
A
to a
B
, even if that function were inlined (Though when I experimented with this I found that in order to make
AtoBAdapter
implement
B
it had to box it, so I didn’t bother.)
I suspect on the JVM I’d be talking about syntax sugar for what I currently do.
d
Well, not particular helpful to your overall problem but you can reduce the boiler plate for those shared members by implementing
A
as well and rely on delegation, which might definitely be a bit odd tbh
Copy code
class AtoBAdapter(a: A): A by a, B {
    override fun z(): Boolean = x.toIntOrNull() == y
}
👌 1
r
Excellent, thanks - hadn’t noticed that! That gives me most of what I wanted. Intriguing that the compiler can prove that `B`’s contract is met there, but can’t allow me to do this:
Copy code
class AtoBAdapter(a: A): B by a {
  override fun z(): Boolean = x.toIntOrNull() == y
}
c
I'd love to have that feature as well and I even think it was considered
r
That link points out you can inline the adapter class into the
asB
extension function:
Copy code
fun A.asB(): B = object : A by this, B {
  override fun z(): Boolean = x.toIntOrNull() == y
}
Not sure if there are any performance implications of the anonymous inner class there? Makes the adaptation from
B
to
A
very simple:
fun B.asA(): A = object : B by this, A {}
c
Well first of all it breaks identity
r
True, and means the result can’t implement both types.
c
exactly - things like
A by this
might work for certain use-cases but certainly not for all (especially not for closed
A
types)
j
@raulraja might have an idea about type promotion