2
\$\begingroup\$

In Java, I use a LoadingCache which offers weakKeys and I need something similar in Typescript, so I wrote the following:

function loadingWeakCache<K extends object, V>(loader: (k: K) => V) : ((k: K) => V) {
    const cache = new WeakMap<K, V>();
    return function(k: K) : V {
        let v = cache.get(k);
        if (v !== undefined) return v;
        v = loader(k);
        cache.set(k, v);
        return v;
    };
}

It seems to work and I'd like it to be reviewed*

Unfortunately, I need to cache a two-argument function. My first attempt was

function pairLoadingWeakCache<K1 extends object, K2 extends object, V>(loader: (k1: K1, k2: K2) => V) : (k1: K1, k2: K2) => V {
    const cache = new WeakMap<K1, (k2: K2) => V>();
    return function(k1: K1, k2: K2) : V {
        let second = cache.get(k1);
        if (second !== undefined) return second(k2);
        const v = loader(k1, k2);
        second = loadingWeakCache(k => loader(k1, k));
        cache.set(k1, second);
        return second(k2);
    };
}

which was wrong as it prevented collecting the second key because of it being referenced from the closure. I'm only presenting it here as it's a smart but broken idea someone could propose. I rewrote it as

function pairLoadingWeakCache<K1 extends object, K2 extends object, V>(loader: (k1: K1, k2: K2) => V) : (k1: K1, k2: K2) => V {
    const cache = new WeakMap<K1, WeakMap<K2, V>>();
    return function(k1: K1, k2: K2) : V {
        let second = cache.get(k1);
        if (second === undefined) {
            second = new WeakMap();
            cache.set(k1, second);
        } else {
            const v = second.get(k2);
            if (v !== undefined) return v;
        }
        const v = loader(k1, k2);
        second.set(k2, v);
        return v;
    };
}

and I'd like it to be reviewed* as well.


* Just please ignore my single-line conditionals as it's my strongly preferred way.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.