Vague feature proposal about a typesafe KProperty.getDelegate()

Part 1: Typesafe getDelegate

The first part of my proposal is a typesafe getDelegate. The kotlin compiler knows what the delegate class is at some point, right? So I am not sure why getDelegate doesn’t have the ability to be typesafe.

One way to achieve this is to introduce another generic into KProperty classes. For example:

public actual interface KProperty0<out V, D> : KProperty<V>, () -> V {
public actual fun get(): V
public fun getDelegate(): D
override val getter: Getter<V>
public interface Getter<out V> : KProperty.Getter<V>, () -> V
}

Part 2: getDelegate Syntax Shortcut

My second proposal is a syntax shortcut. For example, maybe three colons ::: could get to the typed delegate instead of the KProperty.

So

someObject::someProperty.getDelegate()

becomes

someObject:::someProperty

Part 3: Ability to Set Delegate Access Modifier

I have found that KProperty0.getDelegate actually requires using reflection to increase access privileges. So the third part of my proposal is the ability to explicitly set the access privileges of a delegate like so:

class SomeClass{
val someProp by public SomeDelegate()
val someProp2 by internal SomeDelegate()
}

With private staying as the default when by is used alone.

This could also mean that the compiler and IDE could throw errors if you try to use getDelegate on a KProperty that hasn’t set its access to the necessary level.

Use Case

I delegate my kotlin properties to JavaFX Properties. If I want to access the JavaFX Property itself (for example, if I want to to a binding) I use getDelegate. But this is not typesafe so there is no way to ensure that any particular property is backed by one of my JavaFX delegates. My code currently runs without error, but it’s very ugly and unstable because of the lack of accessing getDelegate in a typesafe way and requires type casting.

I know this proposal has a long way to go. I wanted to gather some initial feedback on if this is even remotely possible or useful…

1 Like

Part 1 is not feasible because it would require adding another type parameter to KProperty interfaces, which is a breaking change. Even if it wasn’t, it’d be inconvenient to have another type parameter in a core class for the use case which is not very important or popular.

Part 2 is also unfortunately not feasible because the idea of a property in Kotlin is something that encapsulates its implementation (a field or delegate) and accessors. If you introduce a special syntax which affects how delegated properties can be used, the user can no longer freely change the property implementation, for example making a delegated property non-delegated, without breaking client code. So the fact that the property is delegated becomes a part of its API, which contradicts the goal properties have in Kotlin.

Part 3 is interesting, although I’d prefer an approach that wouldn’t change the language syntax, for example an annotation:

@JvmPublicDelegate
val someProp by SomeDelegate()

Such annotation would behave very similarly to @JvmField annotation which exposes the property’s field as public on JVM.

1 Like