I'm using core.cache
in combination with LazyMap
. Lazy maps are map-like objects (new data type encapsulating maps and adding some logic to auto-force delayed values associated with keys).
When I started putting lazy maps as values of FIFO Cache I observed that all values are being realized just after the map lands in cache. After some digging I've found that it is caused by expression (= ::expired v)
in clojure.core.cache.wrapped/lookup-or-miss
.
What happens is that =
internally calls clojure.lang.Util/equiv
(since LazyMap
implements IPersistentCollection
) and then, after some dispatching, equiv
is called to check whether the contents of a lazy map equals to other object (implicitly other map). This is the desired behavior and lazy map realizes all values to make comparison possible.
However, when comparing a map-like object to something which is not a map (nor a collection), short-circuit would be welcome as soon as we know that it will for sure return false
. But changing that is probably more related to Clojure itself and things like CLJ-1375.
What could be done on core.cache
's side, if that's not too problematic, would be a replacement of
(= ::expired v)
with (identical? ::expired v)
in clojure.core.cache.wrapped
.
It would not only fix corner cases like mine but also speed things up a bit (explicit referential equality rocks when it comes to Clojure keywords).
Other expressions where that could be changed (just in case) are:
(= ::nope ret)
and (= ::nil v)
from clojure.core.cache
.