Enhancment of merge-with

12 views
Skip to first unread message

Konrad Hinsen

unread,
Feb 24, 2010, 11:25:57 AM2/24/10
to cloju...@googlegroups.com
The current implementation of merge-with requires that all its arguments implement clojure.lang.IPersistentMap (which is to be expected), but also that the first argument implements clojure.lang.IFn in the same way as the built-in map types do. This means it doesn't work when the first argument is something else, such as an instance of a deftype with the automatically generated implementation of clojure.lang.IPersistentMap.

This is trivial to fix: replace (m k) by (get m k) in line 2053 of core.clj.

I'd happily provide a ticket with a patch if this is welcome.

Konrad.

Allen Rohner

unread,
Feb 24, 2010, 12:15:39 PM2/24/10
to Clojure Dev
This is a specific instance of a more general problem, that deftype
IPersistentMap implementation of cons does not have the same
functionality as APersistentMap.cons http://www.assembla.com/spaces/clojure/tickets/231

I wrote a patch for that issue. Rich didn't apply it because it's not
fast enough, and I haven't found the time to speed it up yet. If you
want to help, you can optimize the patch.

Allen

Allen Rohner

unread,
Feb 24, 2010, 3:58:04 PM2/24/10
to Clojure Dev
Actually, I misspoke. I was thinking of a different bug, in merge, not
merge-with.

Rich Hickey

unread,
May 27, 2010, 8:29:48 AM5/27/10
to cloju...@googlegroups.com

Patch welcome, thanks!

Rich

Jason Wolfe

unread,
Jun 4, 2010, 3:31:04 PM6/4/10
to Clojure Dev
Along the same lines, it looks like merge and merge-with don't
currently use transients; I think it would be great if they did.

I think merge could be redefined as just:

(defn merge
([] {})
([m1 & maps] (into m1 maps)))

which takes advantage of the transient path of into.

Merge-with would have to be rewritten to explicitly use transients,
along the same lines as into.

I can provide a patch for one or both of these, if desired.

-Jason
Reply all
Reply to author
Forward
0 new messages