faster, more flexible dispatch for clojure.walk


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.

Patch: 0002-CLJ-1239-protocol-dispatch-for-clojure.walk.patch

Performance: My tests indicate this is 1.5x-2x the speed of the original clojure.walk. See 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




Ben Sless
November 21, 2020, 4:41 PM

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.

David Bürgin
May 21, 2018, 9:36 PM

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.

Nicola Mometto
February 27, 2014, 11:17 PM

Alex, for what it matters clojure-1.6.0 after CLJ-1105 exibits the same behaviour as described by Chouser for this patch

Alex Miller
February 27, 2014, 9:54 PM

@Chouser - Never mind! I was thinking this was the change that went into 1.6. Carry on.

Alex Miller
February 27, 2014, 8:11 PM

@Chouser, can you file a new ticket related to this? It's hard to manage work on something from comments on a closed ticket.

Your pinned fields
Click on the next to a field label to start pinning.


Stuart Sierra


Stuart Sierra