Skip to content

Safer equivalence testing for IPersistentCollection implementation#1

Open
siefca wants to merge 1 commit into
raxod502:masterfrom
siefca:safe-equality
Open

Safer equivalence testing for IPersistentCollection implementation#1
siefca wants to merge 1 commit into
raxod502:masterfrom
siefca:safe-equality

Conversation

@siefca
Copy link
Copy Markdown

@siefca siefca commented Mar 2, 2023

I hit the issue when trying to use lazy maps as values of an underlying map of FIFO Cache (provided by clojure.core.cache). After calling clojure.core.cache.wrapped/lookup-or-miss to add a lazy map as (missing) value associated with some cache key, it was always added in realized form.

After debugging I've found that the issue was a part of code where clojure.core/= was called to compare a value v (holding a lazy map) with a special value signalizing expiration: ::expired. By default the = function uses clojure.lang.Util/equiv to compare two objects and equiv calls clojure.lang.Util/pcequiv when at least one of the compared objects implements clojure.lang.IPersistentCollection. Then, pcequiv picks one of the objects implementing IPersistentCollection and calls .equiv on it with other object's value passed as an argument.

As a result comparing lazy map with any value (like keyword, symbol or a number) causes full realization of delayed values. It is ok for comparing with other collections but when it comes to obviously non-matching objects (not collections), causes unexpected side-effects. Comparing a value with a keyword is common practice to handle special cases and therefore we should expect more scenarios like that.

Until Clojure will be changed to resolve the issue (see CLJ-1375) and/or = will be replaced by identical? in core.cache, it would be helpful to apply a workaround (the additional testing is very cheap operation).

See also:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant