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

+1 vote
in Collections by
edited by

Thanks as ever for Clojure- we love it, and use it all day every day to solve worthy problems in ways that delight us as programmers and wow our users as well.


I was naively taking set differences, hoping for this, and was pleased:

> (clojure.set/difference #{:a :b :c} '(:a 1 2))
#{:c :b}

Then I did this, and was surprised:

> (clojure.set/difference #{:a :b :c} '(:a 1 2 3))
Execution error (IllegalArgumentException)
contains? not supported on type: clojure.lang.PersistentList

Then I read the implementation of clojure.set/difference, and I get it now:

https://github.com/clojure/clojure/blob/a29f9b/src/clj/clojure/set.clj#L49-62

But, I do wonder if it would be funner if this just worked. And since funner is probably a more important criteria to me than it is to you, I wonder what the real tradeoffs are here.

  • Is it performance?
  • Or, what would be the downside of implicitly converting to something that implements contains? at the critical moment?

1 Answer

+1 vote
by
selected by
 
Best answer

See https://clojure.atlassian.net/browse/CLJ-2433 (and the various tickets referenced in it).

This is probably something that should be on https://clojure.org/guides/faq since it is asked by almost every new-to-clojure.set developer: clojure.set functions are only defined on sets -- the docstrings do not say what will happen if you pass something that isn't a set.

by
Appreciate the links- I learned a lot. I'd definitely be in favor of an implementation of `clojure.set/difference` that took a sequence as a second argument. In my case I've found a nice workaround of `(apply disj ...)`. Stay rad.
...