CLOVIS
05/22/2023, 8:02 PMis check on all platforms? Is there some hidden cost, or is it safe to use in performance-sensitive applications?ephemient
05/22/2023, 8:10 PMis checks is typically slower than using the JVM's built-in virtual dispatchCasey Brooks
05/22/2023, 8:10 PMis (instanceof in Java) operator was one of the biggest contributors to performance issues. It’s probably worse in old Java apps which had deep class hierarchies, but not quite as terribly expensive in the typical Kotlin appephemient
05/22/2023, 8:10 PMephemient
05/22/2023, 8:11 PMinstanceof Class is probably faster than instanceof Interface because the former only needs to scan the linear superclass hierarchy whereas superinterfaces form a treeCasey Brooks
05/22/2023, 8:11 PMephemient
05/22/2023, 8:12 PMCLOVIS
05/22/2023, 8:22 PMobject implementations, expecting the user to combine them via interface delegation. However, one of the downside of interface delegation is that an implementation's methods cannot be overridden by the final object (since it's delegation, not overriding):
interface A {
fun a()
]
interface B {
fun b()
}
object FooDefault : A, B {
override fun a() = println("FooDefault.a")
override fun b() = println("FooDefault.b")
}
object Custom : A, B by FooDefault {
override fun a() = println("Custom.a")
}
Custom.b()
Output:
println("FooDefault.b")
println("FooDefault.a")
Whereas I would like to see
println("FooDefault.b")
println("Custom.a")
Instead, I thought of letting the caller know which implementation it was called on, and having each implementation call other methods as (implementation as? A) ?: thisCasey Brooks
05/22/2023, 8:31 PMCLOVIS
05/22/2023, 8:32 PMFooDefault.b calls a() .CLOVIS
05/22/2023, 8:33 PMephemient
05/22/2023, 8:33 PMinterface FooDefault : A, B
class Custom : FooDefaultCasey Brooks
05/22/2023, 8:38 PMCLOVIS
05/22/2023, 8:38 PMCLOVIS
05/22/2023, 8:41 PMA and B , so it's not feasible to implement them in a single object. However, if I use delegation to implement them separately, they can't call each other…Casey Brooks
05/22/2023, 8:42 PMCLOVIS
05/22/2023, 8:47 PMFor this case, since A and B are clearly related in some way, you might just want to move them into the same interface, so it’s clear that the two are able to talk to each other.It's true that this would make everything simpler, however in the real case there are dozens of sub-interfaces which all have 1--20 methods, so moving everything in a super-interface is not great 😕 As you can see, the main issue in this example is that
DefaultB needs an instance of A . The problem is, this dependency is specific to DefaultB , not to all implementations of B (otherwise, I would have had B : A to make it explicit). So DefaultB must allow the end-user (who defines the Custom object) to control which instance of A is used, otherwise the end-user can never override A.a .Casey Brooks
05/22/2023, 8:51 PMCLOVIS
05/22/2023, 8:52 PMCasey Brooks
05/22/2023, 8:57 PM