I had an idea for KEEP and I wanted to know if it ...
# language-proposals
a
I had an idea for KEEP and I wanted to know if it is viable or if someone has already proposed something similar I would like to propose the creation of
implement
statements, they would serve as an alternative way to create extension members
Copy code
kt
class Foo {
 val bar = "hi"
}
implement Foo {
 val baz get() = "$bar, kotlin!" // would work like val Foo .baz get() = "$bar, kotlin!" 
}
syntax sugar for interface implementation wrappers for existing classes, when used in classes from other libraries
Copy code
kt
class ExternalClass {
 val foo= "hi"
}

interface MyInterface {
 fun getText(): String
}

implement ExternalClass : MyInterface {
 override fun getText() = foo
}

// internally creates a wrapper
@JvmInline
value class MyInterfaceExternalClass(val value: ExternalClass) : MyInterface {
 override fun getText() = value.foo
}

// when ExternalClass is used in contexts that require MyInterface, internally the wrapper will be used, but in practice, you can use it as if it were actually ExternalClass

fun myFun(arg: MyInterface) {
 println(arg.getText())
}

val obj = ExternalClass()

myFun(obj) // prints "hi"
and for separating classes in multiple files, but uniting everything in a single class, when used in project classes
Copy code
// a.kt
class Class {
 [...]
}

// b.kt
implement Class {
 [...]
}

// c.kt
implement Class : MyInterface {
 override fun getText() =randomValue
 [...]
}
in my opinion this would be viable and useful, what do you think?
j
Value classes which implement an interface force boxing, so calls to
myFun
with the same instance twice, will actually cause two different boxing operations and not support referential equality (which may be required for something like an add/remove listener).
a
I think the same thing happens if you make the wrapper without this method, right? This would be a method of automatically creating the wrapper and converting the class when it is used in the context of the interface. In the context where you need to use the interface, it will be treated as an object that implements the interface like any other.
j
The same thing does happen, but wrapping is explicit and the assumption of referential equality is not present.
If you implement the interface directly you don't have this problem
a
This case is for when you need to implement an interface to an external class, from another library, in this case it is not possible to implement an interface
j
I understand that, but the semantics are very different and that has important implications. If you blindly start using that object as if it actually implemented the interface you're going to cause a lot of boxing and potential logic bugs because of the absence of referential equality. Your syntax is already 90% of what you'd write for a manual wrapped class, and with that the lifetime of the wrapper is now explicit rather than implicit.
a
but from the moment it is converted to the wrapper, it will be used according to the interface, it will be used with the cast of the interface and not of the class in question it will be a
MyInterfaceExternalClass
object that will be put as an argument, however, it will be cast to
MyInterface
if it were necessary to cast to
ExternalClass
, it might just not be possible or it could be cast back to
MyInterfaceExternalClass
and get the value then the value would always be the wrapper, however, it would be used as
MyInterface
j
If you call
myFun
twice in your example you get two allocations of wrappers (the inline and value part of the class are useless because it implements an interface)
a
then it could be implemented that the wrapper is created once and then used in cases where it is needed, so it would be a single wrapper