Kotlin doesn’t force us to use ReadOnlyProperty and ReadWriteProperty when we want to use delegation. And it’s great because it gives us the possibility to use extension functions. But why not declare these interfaces in all places where it’s possible?
Example (Lazy interface isn’t inhereted from ReadOnlyProperty):
I’m implementing factory pattern using delegation. Because It gives me more flexibility:
interface Factory {
val view: ReadOnlyProperty<Any?, View>
// ...
}
And I want to implement view property using lazy. So I write:
object FactoryImpl : Factory {
override val view: ReadOnlyProperty<Any?, View> = lazy { ViewImpl() } // won't compile
}
But I can’t do this because lazy function returns Lazy interface which isn’t inherited from ReadOnlyProperty. Delegation feature for Lazy implemented via extension function:
public inline operator fun <T> Lazy<T>.getValue(thisRef: Any?, property: KProperty<*>): T = value
And I believe that I understand why Kotlin team did this via extension function not via member function. Because they consider Lazy as separate service. It’s not connected with delegation. Delegation is additional possibility which shouldn’t be mentioned in Lazy interface. I understand their decision but I still believe that code above should compile.
As possible solution for Kotlin team I offer to create new interface called something like LazyProperty:
interface LazyProperty<in R, out T> : Lazy<T>, ReadOnlyProperty<R, T>
And lazy function should return this LazyProperty.
Conclusion
In my opinion this problem and problem that ReadWriteProperty is not inherited from ReadOnlyProperty makes working with delegation objects difficult especially for library makers who may want to operate with ReadOnlyProperty and ReadWriteProperty objects.