Search code examples
common-lispsbcl

Would like to understand why the SOME function in examples below are returning inconsistent results


I'm new to common lisp, and I am using SBCL (version 2.1.5) in linux, I am learning about the SOME applicative operator, and I ran these 2 examples that seem to me to be giving inconsistent results:

  • (some #'= '(1 2 3 4 5) '(5 4 3 2 1)) T

  • (some #'= '(1 2 3 4) '(4 3 2 1)) NIL

The first invocation makes sense to me, but the second invocation seems to be inconsistent. Why wouldn't the second invocation also return 'T' like the first invocation?

Thanks for any help understanding this.


Solution

  • (some #'= '(1 2 3 4) '(4 3 2 1))
    

    means

    (or (= 1 4)
        (= 2 3)
        (= 3 2)
        (= 4 1))
    

    That is: the function = is applied to the first elements of the given sequences, then to the second elements and so on. It finishes as soon as one of the sequences is exhausted.

    If you want to have the set intersection between two lists (the :test is a bit redundant here, because the default test eql also compares numbers):

    (intersection '(1 2 3 4) '(4 3 2 1) :test #'=)
    

    This returns the entire intersection. If you only need to test whether there is any common member, finishing as soon as one is found, you could do it like this:

    (find-if (lambda (e)
               (member e '(4 3 2 1)))
             '(1 2 3 4))
    

    or

    (loop :for e :in '(1 2 3 4)
          :thereis (member e '(4 3 2 1)))