For DSLs, it would be nice to be able to overload ...
# language-proposals
j
For DSLs, it would be nice to be able to overload
ReadWriteProperty#setValue
so that we could set a variable from different types. Something like this:
Copy code
import kotlin.reflect.KProperty

interface Named {
  val name: String
}

class MyClass {
  var name by NameDelegate("foo")
}

class NameDelegate(private var name: String) {
  operator fun getValue(thisRef: MyClass, property: KProperty<*>): String {
    return name
  }

  operator fun setValue(thisRef: MyClass, property: KProperty<*>, value: String) {
    name = value
  }

  operator fun setValue(thisRef: MyClass, property: KProperty<*>, value: Named) {
    name = value.name
  }
}

fun main() {
  val namedImpl = object : Named {
    override val name: String = "bar"
  }

  val myObject = MyClass()
  myObject.name = "bar" // this compiles
  myObject.name = namedImpl // this does not compile
}
h
I think this could also be solved with an
or
operator in type parameters (which has been proposed numerous times), but your idea is simpler:
Copy code
operator fun setValue(thisRef: MyClass, property: KProperty<*>, value: String | Named) {
    name = value.toString()
}
k
What type would that make
name
? The way it works right now is that a property has a single type and both the setter and getter share that type.
i
I think it boils down to an ability to override setters in general: https://youtrack.jetbrains.com/issue/KT-4075
j
Yes exactly @ilya.gorbunov ! That would be awesome 🙂
@karelpeeters name would be a String (what the getter returns)
I could make it explicit by making
NameDelegate
implement
ReadWriteProperty<MyClass, String>