I want to memorize the result of an expensive calc...
# getting-started
s
I want to memorize the result of an expensive calculation for a computed property. What's a good approach here? The
AppState
is part of a redux pattern and will be copied often using
appState.copy()
Only when the input properties change this needs to be calculated again. Just like
remember(allPhotos, openSimilarityGroups) {  }
in a Composable context. Here I don't have that. ( Previously I calculated the new list in my
AppStore
, but there are so many places this is necessary that it got confusing. So I want the AppState to always have a valid value without this being set from the outside. ) ChatGPT's solution is using a mutableMap, but that thing will of course grow. I feel there must be something neat built into Kotlin that I don't find right now.
Copy code
data class AppState(

    val allPhotos: ImmutableList<Photo> = persistentListOf(),
    val openSimilarityGroups: ImmutableSet<Int> = persistentSetOf()
    // .. lots of other properties ...

    ) : State {

    val allPhotosCollapsed: ImmutableList<Photo> by lazy {
        createCollapsed(allPhotos, openSimilarityGroups)
    }

    // ... other computed properties ...

    companion object {

        private fun createCollapsed(allPhotos: List<Photo>, openedSimilarityGroups: Set<Int>): ImmutableList<Photo> {

            // TODO should return remembered result list if parameters did not change.
            //   should be thread safe and only remember one result
            return resultOfExpensiveCalculation
        }
    }
}
l
I remember that there was a Memoization feature built into Arrow Memoization | Arrow (arrow-kt.io)
👍 1
thank you color 1
t
I don't think there's anything built in similar to Python's
@functools.lru_cache
. You'll likely need a library (or just write a version with a global mutable map and some concurrency-safe access to it.) Just make sure to consider whether you want cache eviction in your solution.
thank you color 1
s
Interesting. Arrow uses a Map. Wrapped into an Atomic - I guess for thread safety.
Looks like I won't find a better solution than what Arrow offers. Hopefully such a feature will one day be included in stdlib. Arrow has many nice features that should be part of stdlib 😄
s
Thanks, but Caffeine is not multiplatform and cache4k runs in a coroutinescope. It looks like that Arrows memoize() is the closest thing to what I need.