Search code examples
setcommon-lispsbcl

Does the adjoin Operation in SBCL Always Involve a Search?


The Common Lisp Hyperspec gives the following equivalence for the adjoin function on a set:

(adjoin item list :key fn)
   ==  (if (member (fn item) list :key fn) list (cons item list))

But does this mean an implementation, in particular SBCL, necessarily searches the corresponding list for the item? I'm wondering about simply using adjoin as a test for set membership, but only if the implementation automatically represents certain sets efficiently as a hashtable, bit vector, etc, allowing lookup instead of search.

(if (eq (adjoin item set) set)
  'item-present
  'item-absent)

I have the same question about how alexandria:setp is implemented. Of course, the other option is to appropriately represent the set myself, but I'd like to take advantage of the internal SBCL or alexandria optimizations if feasible.


Solution

  • It is easy to verify by suitable use of meta-. that neither SBCL's adjoin nor alexandria's setp do any deep magic. As Barmar points out in a comment it's almost inconceivable that they should.

    However if you want a test for set membership of sets represented as lists, there is one: it's called member. It, also, won't do any magic.