You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
val optionallyRequiredValue by lazy {
scope.async {
// ...
}
}
The latter option doesn't spawn unnecessary new child coroutines (which could stop the scope from completing if you aren't careful).
Or let's say you have something similar to
val sendOnes = scope.launch(start =CoroutineStart.LAZY) {
while (true) { onesChannel.send(1) }
}
Then, you have to write things like sendOnes.start(); channel.receive() throughout your codebase. But how is this better than something like the following?
val onesChannel by lazy {
Channel<Int>().also {
scope.launch {
while (true) { onesChannel.send(1) }
}
}
}
I can sort of see the utility of LAZY when you have to combine on-demand computation with the ability to reinitialize the variable anew:
@Volatile // or @Synchronizedvar latestResult:Deferred<Int> = computeResult()
privatefuncomputeResult(): Deferred<Int> = scope.async(start =CoroutineStart.LAZY) {
// ...
}
funupdate() {
// latestResult?.let { it.cancel() } // can't do that: the clients will throw
latestResult = computeResult()
}
But this looks to me like a good fit for a hot Flow chain: mutable state in concurrent scenarios is tricky to get right, it's best avoided, not to mention that this allows for many parallel computeResult() computations, which can DDoS the system.
The existence of LAZY led people to writing code that's more difficult to follow than the alternative without it. If LAZY really is a situationally useful thing at best, we could mark it as Delicate. If it is useless, we can deprecate it. For now, we can edit the docs, but in general, we should deliberately research how it's used in some larger codebases.
The text was updated successfully, but these errors were encountered:
Copying from #4147 (comment):
How does one use
LAZY
? Typically, in a pattern likeBut I don't see how this is better than
The latter option doesn't spawn unnecessary new child coroutines (which could stop the scope from completing if you aren't careful).
Or let's say you have something similar to
Then, you have to write things like
sendOnes.start(); channel.receive()
throughout your codebase. But how is this better than something like the following?I can sort of see the utility of
LAZY
when you have to combine on-demand computation with the ability to reinitialize the variable anew:But this looks to me like a good fit for a hot
Flow
chain: mutable state in concurrent scenarios is tricky to get right, it's best avoided, not to mention that this allows for many parallelcomputeResult()
computations, which can DDoS the system.I'm really struggling to think of a use case where
CoroutineStart.LAZY
is actually the superior option. When I search grep.app forLAZY
usages, most of them are completely unclear to me and seem to have been created by accident, like https://github.com/Baeldung/kotlin-tutorials/blob/f203e8fd8571b8dcc313fca04c72196bc4948649/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductControllerCoroutines.kt#L31-L44 Why is thisLAZY
if it's immediately started?https://github.com/JetBrains/compose-multiplatform/blob/6aad20ec087f54df168ad7e7ce03c4ded710a93c/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/AsyncCache.kt could be a mistake, or it could actually be dictated by some requirement to avoid deadlocks if
CoroutineDispatcher.dispatch
callsgetOrLoad
. I'm not sure.The existence of
LAZY
led people to writing code that's more difficult to follow than the alternative without it. IfLAZY
really is a situationally useful thing at best, we could mark it asDelicate
. If it is useless, we can deprecate it. For now, we can edit the docs, but in general, we should deliberately research how it's used in some larger codebases.The text was updated successfully, but these errors were encountered: