Is there a better way to do memoization? ```import...
# coroutines
d
Is there a better way to do memoization?
Copy code
import kotlinx.coroutines.*

@JvmName("_memoize_receiver")
fun <T,R> (suspend (T) -> R).memoize(): suspend (T) -> R {
    val memos = mutableMapOf<T, Deferred<R>>()
    val f = this
    return { t ->
        coroutineScope {
            withContext(coroutineContext + <http://Dispatchers.IO|Dispatchers.IO>) {
                synchronized(memos) {
                    memos.computeIfAbsent(t) { async { f(t) } }
                }
            }.await()
        }
    }
}

fun <T,R> memoize(f: suspend (T) -> R): suspend (T) -> R = f.memoize()
I guess notably it suspends instead of blocking by virtue of the mutex use.
👍 1
d
Yeah that mutex is exactly what I'm looking for
blocking within
IO
seems bad, where avoidable
y
That's a nice library function. Would it be easy/possible to adapt that to work for any shape function? e.g. two args instead of zero args?
I hope at some point there is a memoize tied to coroutine scopes. Provided by the standard libraries. Tying to a request, or application seems very natural.
a
My implementation:
Copy code
suspend inline fun <R> (suspend () -> R).memoize(): suspend () -> R {
    val Undef = object {}
    var value: Any? = Undef
    return suspend {
        if (value === Undef) value = this() as Any?
        value as R
    }
}