Erik
11/04/2024, 12:12 PMargument: () -> Unit = {}
) aren't evaluated more than once if the function with that default argument is called more than once. I.e., the {}
literal lambda is only instantiated once. When is it instantiated for the first time? I assume the first time the default is actually required. And how long does the produced literal value remain in memory? Forever? Until the function is no longer referenced (e.g. on JVM garbage collection). In other words: is the literal, in fact, a singleton? This might be important to know if the default object is heavy on resources, like memory.Klitos Kyriacou
11/04/2024, 12:36 PMemptyList()
return a cached collection, because they can easily do that, but on the other hand it's not easy for emptyArray()
to return a cached empty array because arrays carry the element type with them, so to return a cached empty array would involve caching arrays of every conceivable element type, so instead emptyArray<SomeType>()
creates a new Array<SomeType>
.Erik
11/04/2024, 1:01 PMErik
11/04/2024, 1:03 PM{}
, when used as a default. At least on JVM, that is some kind of Function
object instance. When it is instantiated once, will it remain in memory forever? Or could the literal be evaluated a second time under some specific circumstances?Klitos Kyriacou
11/04/2024, 1:19 PMfun main() {
val f1: () -> Unit = {}
val f2: () -> Unit = {}
val fnset = mutableSetOf<() -> Unit>()
for (i in 1..1000) {
val fn: () -> Unit = {}
fnset.add(fn)
}
check(f1 !== f2)
check(fnset.size == 1) // Because we added the same instance of the lambda each time
}
That just demonstrates it without using functions or default function parameters. In fact, it's the same with default parameters:
val fnset = mutableSetOf<() -> Unit>()
fun foo(lambda: () -> Unit = {}) {
fnset.add(lambda)
}
fun main() {
for (i in 1..1000) {
foo()
}
check(fnset.size == 1) // Because we added the same instance of the lambda each time
}