5

Why the following in emacs-lisp works as expected:

(set-difference '(1 2) '(1))
=> (2)

But if strings used it doesn't:

(set-difference '("foo" "bar") '("foo"))
=> ("foo" "bar")

How do can I calculate set difference for sets of strings?

6

It is for the same reason that:

(eql "foo" "foo")
=> nil

Along with the other cl-lib sequence functions generally, set-difference (aka cl-set-difference) defaults to using eql for its equality test, and therefore in your example none of the members of the first set are present in the second set.

You can tell it what to use for its equality test, however:

(set-difference '("foo" "bar") '("foo") :test #'equal)
=> ("bar")
  • Oh wow. I wasn't sure how to use the third arguments. Thank you very much! Sad that docstings in Emacs lisp almost never contain any examples. – iLemming Oct 7 at 3:57
  • 1
    @iLemming seq-difference is an alternative to cl-set-difference and its argument is simpler: (seq-difference SEQUENCE1 SEQUENCE2 &optional TESTFN). Many cl-* functions use eql by default, while I usually need eq or equal. – xuchunyang Oct 7 at 4:03
  • 2
    The documentation for the various cl-lib facilities can seem a bit spartan, I agree, but this can be due to particular common concepts being explained in their own section elsewhere. I recommend reading C-h i g (cl)Sequence Basics – phils Oct 7 at 4:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.