Welcome! Please see the About page for a little more info on how this works.

+8 votes
in Collections by

Examples that work as expected:

`
Clojure 1.7.0-master-SNAPSHOT
user=> (dissoc {})
{}
user=> (disj #{})

{}

user=> (conj {})
{}
user=> (conj [])
[]
`

Examples that do not work as desired, but are changed by the proposed patch:

`
user=> (assoc {})
ArityException Wrong number of args (1) passed to: core/assoc clojure.lang.AFn.throwArity (AFn.java:429)
user=> (assoc! (transient {}))
ArityException Wrong number of args (1) passed to: core/assoc! clojure.lang.AFn.throwArity (AFn.java:429)
user=> (dissoc! (transient {}))
ArityException Wrong number of args (1) passed to: core/dissoc! clojure.lang.AFn.throwArity (AFn.java:429)

;; patch enables conj! with multiple arguments, like conj
user=> (conj! (transient []) 1 2 3)
ArityException Wrong number of args (4) passed to: core/conj! clojure.lang.AFn.throwArity (AFn.java:429)

;; patch would give error for missing value for last key to assoc!, not silently use nil for last value
user=> (assoc! (transient {}) 1 2 3)

object[clojure.lang.PersistentArrayMap$TransientArrayMap 0x2e7569b8 "clojure.lang.PersistentArrayMap$TransientArrayMap@2e7569b8"]

`

I looked through the rest of the code for similar cases, and found that there were some other differences between them in how different numbers of arguments were handled, such as:

  • conj handles an arbitrary number of arguments, but conj! does not.
  • assoc checks for a final key with no value specified (CLJ-1052), but assoc! did not.

History/discussion: A discussion came up in the Clojure Google group about conj giving an error when taking only a coll as an argument, as opposed to disj which works for this case:

https://groups.google.com/forum/?fromgroups=#!topic/clojure/Z9mFxsTYTqQ

Screened by: Alex Miller

16 Answers

0 votes
by

Comment made by: jafingerhut

clj-1103-make-conj-assoc-dissoc-handle-args-similarly-v1.txt dated Nov 4 2012 makes conj conj! assoc assoc! dissoc dissoc! handle args similarly to each other.

0 votes
by

Comment made by: bbloom

I too ran into this and started an additional discussion here: https://groups.google.com/d/topic/clojure-dev/wL5hllfhw4M/discussion

In particular, I don't buy the argument that (into coll xs) is sufficient, since into implies conj and there isn't an terse and idiomatic way to write (into map (parition 2 keyvals))

So +1 from me

0 votes
by

Comment made by: jafingerhut

Patch clj-1103-2.diff is identical to the previous patch clj-1103-make-conj-assoc-dissoc-handle-args-similarly-v1.txt except it applies cleanly to latest master. The only changes were some changed context lines in a test file.

0 votes
by

Comment made by: jafingerhut

Patch clj-1103-3.diff is identical to the patch clj-1103-2.diff, except it applies cleanly to latest master. The only changes were some doc strings for assoc(image: and dissoc) in the context lines of the patch.

0 votes
by

Comment made by: jafingerhut

Patch clj-1103-4.diff is identical to the previous clj-1103-3.diff, except it updates some context lines so that it applies cleanly to latest Clojure master as of today.

0 votes
by

Comment made by: alexmiller

Can someone update the description with some code examples? Or drop them here at least?

0 votes
by

Comment made by: bbloom

What do you mean code examples?

These currently work as expected:
(dissoc {})
(disj #{})

The following fail with arity errors:
(assoc {})
(conj {})

Similarly for the transient ! versions.

This is annoying if you ever try to do (apply assoc m keyvals)... it works at first glance, but then one day, bamn! Runtime error because you tried to give it an empty sequence of keyvals.

0 votes
by

Comment made by: jafingerhut

Patch clj-1103-5.diff dated Aug 6 2014 applies cleanly to latest Clojure master as of today, whereas the previous patch did not. Rich added 1-arg version of conj to 1.7.0-alpha1, so that change no longer is part of this patch.

0 votes
by

Comment made by: jafingerhut

Patch clj-1103-6.diff dated Aug 29 2014 is identical to the former patch clj-1103-5.diff (which will be deleted), except it applies cleanly to the latest Clojure master.

0 votes
by

Comment made by: jafingerhut

Patch clj-1103-7.diff dated May 25 2015 is identical to the former patch clj-1103-6.diff (which will be deleted), except it applies cleanly to the latest Clojure master.

0 votes
by

Comment made by: michaelblume

Updated patch to apply cleanly to master

0 votes
by

Comment made by: michaelblume

Updated patch

0 votes
by

Comment made by: jafingerhut

Is it intentional that clj-1103-9.patch leaves out the changes to assoc! that were in the earlier patches? I can create another updated one if so -- just curious if there was a reason for the change.

0 votes
by

Comment made by: michaelblume

That was not intentional at all, thanks for catching it, I'm honestly not sure what happened on my end to make that happen. I think this patch should be a correct update. Sorry about that.

0 votes
by

Comment made by: jafingerhut

No worries, and I thank you for keeping the patch current, even while keeping my name on it.

...