Hello everyone. I’m having a hard time with an ext...
# getting-started
t
Hello everyone. I’m having a hard time with an extension function on an out projected type.
fun <Next, Root> KProperty0<Next>.set(value: Next) = Value<Next, Root>(this, value)
Because KProperty0 is out projected, I don’t get any type checking for the value parameter. If the property is a String, I can put an Int in the value because they both inherit from Any. Is there anything I can do to make the type checking more rigid on this function? Looking for a more invariant type checking.
p
This sounds like an XY problem - what's the problem you're trying to solve by extending a KProperty?
t
I'm trying to store the property and value pair in a tree, so I can have a 'patch' object for a data class.
I want a nicer copy function. Here’s the syntax I came up with.
Copy code
val newData = data.copy {
    ::order.set {
        ::customer.set {
            ::name.set {
                ::firstName.set("joe")
                ::lastName.set { it -> it.uppercase() } 
            }
        }
    }
}
// or
val patch: Patch<DataClass> = DataClass::class.patch {
    ::order.set {
        ::customer.set {
            ::name.set {
                ::firstName.set("joe")
                ::lastName.set { it -> it.uppercase() } 
            }
        }
    }
}
// then somewhere else
val newData = data.copyWith(patch)
This works well, other than the syntax allows setting a string property’s value to 0. (Which fails, but at runtime. I would like it to fail at compile time.)
Does this help Paul? Any ideas how to solve this Y?
p
It does help understand what you’re after, but I don’t have a lot of advice… I think you’d need a lower-level hook to really implement this, I don’t think generics (even reified) are sufficient
What you’re proposing sounds similar to the ‘deep mutation’ note in the value classes KEEP: https://github.com/Kotlin/KEEP/blob/master/notes/value-classes.md#deep-mutations
t
Ooh thanks for the link to that keep
p
I think you’d need to build your ‘better copy function’ at compile time to have all the right type information
t
For what it’s worth I found a clunky workaround. If I wrap the KProperty in an object that is invariant. Then use the set value function on that object.
image.png
I don’t like it. But it will do for now. 😕
1