The conditional dispatch in clojure.walk is slow and not open to extension. Prior to CLJ-1105 it did not support records.
Approach: Reimplement clojure.walk using protocols. The public API does not change. Users can extend the walk protocol to other types (for example, Java collections) if desired. As in CLJ-1105, this version of clojure.walk supports records.
Performance: My tests indicate this is 1.5x-2x the speed of the original clojure.walk. See https://github.com/stuartsierra/clojure.walk2 for benchmarks.
Risks: This approach carries some risk of breaking user code that relied on type-specific behavior of the old clojure.walk. When running the full Clojure test suite, I discovered (and fixed) some breakages that did not show up in clojure.walk's unit tests. See, for example, commit 730eb75 in clojure.walk2
@Chouser, can you file a new ticket related to this? It's hard to manage work on something from comments on a closed ticket.
@Chouser - Never mind! I was thinking this was the change that went into 1.6. Carry on.
Alex, for what it matters clojure-1.6.0 after CLJ-1105 exibits the same behaviour as described by Chouser for this patch
The current implementation of clojure.walk does not preserve metadata.
If this new implementation is ever revisited, it would be great to also keep the metadata on the elements where possible.
Added a new patch 0003-CLJ-1239-protocol-dispatch-for-clojure.walk.patch based on the previous one with the following change:
Use into's transducer arity for for most persistent collections. It handles the transient case and makes for cleaner implementation.