clojure.walk/postwalk does not preserve MapEntry type objects
Description
This came up on Slack. A naïve implementation of "lispify" to turn vectors into lists used this code:
But when called like this:
It produces this error: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry
My initial reaction was to change the condition to (and (vector? e) (not (map-entry? e))) but that still failed, because while walking the hash map, the MapEntry [:a "b"] was turned into a PersistentVector.
At this point, we can switch to using prewalk and it works as expected:
Now we get the expected result:
This seems unintuitive at best and feels like a bug: postwalk should preserve the MapEntry type rather than converting it to a PersistentVector.
Cause: The problem seems to be this line https://github.com/clojure/clojure/blob/master/src/clj/clojure/walk.clj#L45:
Proposed: Change to:
This would preserve the type of the subelement.
Patch: clj-2031-w-test-v2.diff
Screened by: Alex Miller
Environment
Activity
It's in a list for Rich to look at.
This keeps coming up on Slack – given there's a patch and this is prescreened, can it just get fixed as part of the next Clojure 1.9.0 Alpha/Beta build?
Good catch, thanks! Added patch clj-2031-w-test-v2.diff that uses key and val instead.
Instead of the calls to .key and .val you should just call key and val.
Added patch with test
Assignee
Reporter
Labels
Approval
Patch
Fix versions
Affects versions
Priority
