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.
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.