https://kotlinlang.org logo
m

Marc Knaup

11/30/2020, 12:33 PM
Idea: auto-generated
equals()
implementation for lambdas.
Copy code
Button(
    label = "Print count",
    onClick = @Equatable { println(count) }
)

data class ButtonProps(val label: String, val onClick: () -> Unit)
That’s useful in Kotlin React development and similar. If the props (arguments) of a component are equal between two rendering attempts then the second rendering can be skipped (memoization). Unfortunately that doesn’t work if the props contain lambdas because they’ll never be equal to the previous instance. React provides a workaround like
val onClick = useCallback(count) { println(count) }
which only uses the passed instance of the lambda if
count
has changed and the previous one otherwise. This is more boilerplate and you have to move the lambda further away from where it’s actually used. More importantly it easily leads to errors where you forget to add a dependency (a bound variable) and therefor an old function with different variable bindings will be used.
@Equatable
could tell the compiler to generate an
equals
method for that lambda which compares all bound variables automatically - in this case
count
. That would solve the issue and eliminate that cause of errors.
d

Dominaezzz

11/30/2020, 6:08 PM
iirc, this is done for
fun interface
so it shouldn't be hard to do for lambdas.
m

Marc Knaup

11/30/2020, 6:09 PM
How’s that done for
fun interface
? 😮 Do you have a link with further info?
d

Dominaezzz

11/30/2020, 6:12 PM
I think I found it in some recent release notes, one sec.
Oops, it's actually this one. https://youtrack.jetbrains.com/issue/KT-33455
m

Marc Knaup

11/30/2020, 6:15 PM
That’s interesting. Thank you 🙂
y

Youssef Shoaib [MOD]

01/19/2021, 3:04 PM
You could consequently make a
fun interface EquitableLambda
and make every react function use that instead of the normal lambda types
m

Marc Knaup

01/19/2021, 3:10 PM
I don’t think that the requirement for being equatable should be on the callee side, but on the call side. I.e. where I create the lambda I should denote that it is
Equatable
, not on the side where React expects a function. Whether a lambda can be made equatable in any meaningful way and without causing negative side-effects can only be determined at the call site. What we could do is to allow
@Equatable
on both sides. The call site makes the compiler implement
equals
. The callee site makes the compiler issue a warning if the lambda passed to such a parameter is not marked
@Equatable
.