Support for multiple key(s)-value pairs in assoc-in

714 views
Skip to first unread message

Griffin Smith

unread,
Jun 28, 2015, 9:24:03 PM6/28/15
to cloju...@googlegroups.com
Was thinking it'd be cool to support multiple key(s)-value pairs in assoc-in just like assoc does. Are there any plans/open patches for this? If not I'd love to write it myself!

Andy Fingerhut

unread,
Jun 29, 2015, 1:20:27 AM6/29/15
to cloju...@googlegroups.com
I am pretty sure there is no ticket in JIRA suggesting such a change.  I don't know whether such a change would be accepted by the Clojure core team or not.

If you do file a ticket, it might be nice to preserve the behavior of assoc where it throws an exception if the last key (or for assoc-in key-vector) does not have a corresponding value.

Andy

On Sun, Jun 28, 2015 at 5:22 PM, Griffin Smith <wildgr...@gmail.com> wrote:
Was thinking it'd be cool to support multiple key(s)-value pairs in assoc-in just like assoc does. Are there any plans/open patches for this? If not I'd love to write it myself!

--
You received this message because you are subscribed to the Google Groups "Clojure Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure-dev...@googlegroups.com.
To post to this group, send email to cloju...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojure-dev.
For more options, visit https://groups.google.com/d/optout.

Alex Miller

unread,
Jun 29, 2015, 6:31:57 AM6/29/15
to cloju...@googlegroups.com
No jira for this to my knowledge, seems like a reasonable enhancement. 

I agree with Andy's suggestion (and there is a ticket to address that for assoc! already).

Griffin Smith

unread,
Jun 29, 2015, 7:27:58 PM6/29/15
to cloju...@googlegroups.com

Alex Miller

unread,
Jun 30, 2015, 8:41:08 AM6/30/15
to cloju...@googlegroups.com
Thinking about this for reals, I don't know how this would work with the current syntax which takes a sequence of keys that is the path:

clojure.core/assoc-in
([m [k & ks] v])

Are you suggesting:
(assoc-in {} [:a :b :c] 1 :d 4

where :d 4 is the extra pair? I think that's unlikely to fly. You can accomplish the same thing now with update-in of course:

(update-in {} [:a :b] assoc :c 1 :d 4)
{:a {:b {:c 1, :d 4}}}

I'm going to decline this ticket - I don't think it makes syntax with how assoc-in is currently defined after I've now thought about it more. But I'm still open to being persuaded. :)

Alex



--

Ambrose Bonnaire-Sergeant

unread,
Jun 30, 2015, 8:48:22 AM6/30/15
to cloju...@googlegroups.com
Repeating the path then applying left-to-right seems like more a natural extension.

(assoc-in {} [:a :b] 1 [:c d] 2 [:e :f] 3)
;=> {:a {:b 1} :c {:d 2} :e {:f 3}}

Thanks,
Ambrose

Alex Miller

unread,
Jun 30, 2015, 9:09:28 AM6/30/15
to cloju...@googlegroups.com
Interesting idea. Any real examples out there where people are working around this?

Joe R. Smith

unread,
Jun 30, 2015, 9:09:54 AM6/30/15
to cloju...@googlegroups.com
I understood the request to be:

(assoc-in [:a :b :c] 1 [:d] 4)

which would be consistent with assoc, but with keypaths.

Alex Miller

unread,
Jun 30, 2015, 9:15:42 AM6/30/15
to cloju...@googlegroups.com
Ok, I've reopened and modified that ticket a bit.

Sean Grove

unread,
Jun 30, 2015, 11:12:55 AM6/30/15
to cloju...@googlegroups.com
I've rubbed up against this several times and wished for the multiple key-paths support in assoc-in, but it's a pretty minor nit.

Paul deGrandis

unread,
Jun 30, 2015, 4:02:32 PM6/30/15
to cloju...@googlegroups.com
I've also rubbed up against this before.  One example that comes to mind: Say you're managing application state in a map (common in something like a CLJS application), and you want to transact in data to that application state.  It's very natural to express that transaction as a series of key paths and values.

In the past, I've put this in a doseq behind another function that runs some validations on the paths and values.

I also agree, this is pretty minor, but the symmetry with `assoc` would be nice.

Cheers,
Paul

Griffin Smith

unread,
Jul 2, 2015, 9:24:22 AM7/2/15
to cloju...@googlegroups.com
The way I'm currently working around it is with `->`, as in:

(-> my-map
(assoc-in [:a :b] 1)
(assoc-in [:c :d] 2)
(assoc-in [:e :f] 3))

fwiw the specific use-case for me was modifying the settings map for
`ring.middleware.defaults/wrap-defaults`.


On 06/30, Alex Miller wrote:
> Thinking about this for reals, I don't know how this would work with the
> current syntax which takes a sequence of keys that is the path:
>
> clojure.core/assoc-in
> ([m [k & ks] v])
>
> Are you suggesting:
> (assoc-in {} [:a :b :c] 1 *:d 4*)
>
> where :d 4 is the extra pair? I think that's unlikely to fly. You can
> accomplish the same thing now with update-in of course:
>
> (update-in {} [:a :b] assoc :c 1 :d 4)
> {:a {:b {:c 1, :d 4}}}
>
> I'm going to decline this ticket - I don't think it makes syntax with how
> assoc-in is currently defined after I've now thought about it more. But I'm
> still open to being persuaded. :)
>
> Alex
>
>
>
> On Mon, Jun 29, 2015 at 6:27 PM, Griffin Smith <wildgr...@gmail.com>
> wrote:
>
> > Opened a JIRA ticket: http://dev.clojure.org/jira/browse/CLJ-1771
> >
> >
> > On Sunday, June 28, 2015 at 9:24:03 PM UTC-4, Griffin Smith wrote:
> >>
> >> Was thinking it'd be cool to support multiple key(s)-value pairs in
> >> assoc-in just like assoc does. Are there any plans/open patches for this?
> >> If not I'd love to write it myself!
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Clojure Dev" group.
> > To unsubscribe from this group and stop receiving emails from it, send an
> > email to clojure-dev...@googlegroups.com.
> > To post to this group, send email to cloju...@googlegroups.com.
> > Visit this group at http://groups.google.com/group/clojure-dev.
> > For more options, visit https://groups.google.com/d/optout.
> >
>
> --
> You received this message because you are subscribed to a topic in the Google Groups "Clojure Dev" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure-dev/08ymJ_3Ln-E/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to clojure-dev...@googlegroups.com.

Herwig Hochleitner

unread,
Jul 8, 2015, 5:01:04 PM7/8/15
to cloju...@googlegroups.com
For the example you posted, I'd use (update-in ks assoc :a 1 :b 2)
For the general pattern, I have played around with something that I call pretial: https://gist.github.com/bendlas/0722a35ab274d659c507
It allows:

(update-in ks apply-to
  (pretial assoc :a 1 :b 2)
  (pretial dissoc :c))

Alex Baranosky

unread,
Oct 3, 2015, 4:20:13 PM10/3/15
to cloju...@googlegroups.com
I've often used the -> as a way to get the same effect, as Griffin showed above.

(-> my-map
      (assoc-in [:a :b] 1)
      (assoc-in [:c :d] 2)
      (assoc-in [:e :f] 3))

However, it did always come as a surprising inconsistency that I couldn't just write that as:

(assoc-in my-map
          [:a :b] 1
          [:c :d] 2
          [:e :f] 3)

I think this would be a good change for consistency reasons, similar to the addition of clojure.core/update in 1.7. Also, this won't effect backwards compatibility in any way.

--
Reply all
Reply to author
Forward
0 new messages