Clojure

Broken update-in for empty keys vector

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Duplicate
  • Affects Version/s: Release 1.4
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None

Description

Using update-in with an empty keys vector produces unexpected results:
(update-in {:a 10 :b 20} [] dissoc :a)
⇒ {nil nil, :a 10, :b 20}
(update-in {:a 10 :b 20} [] assoc :c 99)
⇒ {nil {:c 99}, :a 10, :b 20}

The empty keys vector occurs in scenarios where you search on nested maps and later want to update the nested map structure at found paths.

A well-defined behavior is to check the case when the keys vector is empty and then apply only the given function on the given map: (apply f m args)

Activity

Hide
Nicola Mometto added a comment - - edited

I think passing in an empty vector should rather be considered an error, since the doc specifies that `ks should be a sequence of keys`.

The same wrong (in my opinion) behaviour is shown by assoc-in

user=> (assoc-in {} [] 1)

Unknown macro: {nil 1}
Show
Nicola Mometto added a comment - - edited I think passing in an empty vector should rather be considered an error, since the doc specifies that `ks should be a sequence of keys`. The same wrong (in my opinion) behaviour is shown by assoc-in
user=> (assoc-in {} [] 1)
Unknown macro: {nil 1}
Hide
Gunnar Völkel added a comment - - edited

Specifying an empty vector is no error in case the vector is not manually specified but computed as in the scenario I mentioned above.
"(apply f m args)" in case of an empty vector is the natural continuation of the usual behavior of update-in:

  • update-in with 2 keys the second level map is updated
  • update-in with 1 key the first level map (child of given map) is updated
  • update-in with no key the given map (zero level) is updated.

Otherwise, you will always have to wrap update-in in something like the following when the keys vector is computed:

(if (seq keys) (update-in m keys f args) (apply f m args))

Show
Gunnar Völkel added a comment - - edited Specifying an empty vector is no error in case the vector is not manually specified but computed as in the scenario I mentioned above. "(apply f m args)" in case of an empty vector is the natural continuation of the usual behavior of update-in:
  • update-in with 2 keys the second level map is updated
  • update-in with 1 key the first level map (child of given map) is updated
  • update-in with no key the given map (zero level) is updated.
Otherwise, you will always have to wrap update-in in something like the following when the keys vector is computed:
(if (seq keys) (update-in m keys f args) (apply f m args))
Hide
Andy Fingerhut added a comment -

I believe this is a duplicate of CLJ-373. Please add your comments and/or suggested patches to that ticket rather than this one. This one should likely be closed as a duplicate. Let me know if you can think of any reason why this one covers new ground that CLJ-373 does not.

Show
Andy Fingerhut added a comment - I believe this is a duplicate of CLJ-373. Please add your comments and/or suggested patches to that ticket rather than this one. This one should likely be closed as a duplicate. Let me know if you can think of any reason why this one covers new ground that CLJ-373 does not.
Hide
Gunnar Völkel added a comment -

Yes, you are right - it is a duplicate.

Show
Gunnar Völkel added a comment - Yes, you are right - it is a duplicate.
Hide
Andy Fingerhut added a comment -

Closed, as it is a duplicate of CLJ-373.

Show
Andy Fingerhut added a comment - Closed, as it is a duplicate of CLJ-373.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: