That said, using the built-in set functions makes it easy to write set-manipulation code. And for small sets they may well be more efficient than the alternatives. If profiling shows you that these functions are a performance bottleneck in your code, you can always replace the lists with sets built on top of hash tables or bit vectors.
**ADJOIN**
also takes :key
and :test
keyword arguments, which are used when determining whether the item is present in the original list. Like **CONS**
, **ADJOIN**
has no effect on the original list—if you want to modify a particular list, you need to assign the value returned by **ADJOIN**
to the place where the list came from. The modify macro **PUSHNEW**
does this for you automatically.
The remaining set-theoretic functions provide bulk operations: **INTERSECTION**
, **UNION**
, **SET-DIFFERENCE**
, and **SET-EXCLUSIVE-OR**
. Each of these functions takes two lists and :key
and keyword arguments and returns a new list representing the set resulting from performing the appropriate set-theoretic operation on the two lists: **INTERSECTION**
returns a list containing all the elements found in both arguments. **UNION**
returns a list containing one instance of each unique element from the two arguments.3 **SET-DIFFERENCE**
returns a list containing all the elements from the first argument that don’t appear in the second argument. And **SET-EXCLUSIVE-OR**
returns a list containing those elements appearing in only one or the other of the two argument lists but not in both. Each of these functions also has a recycling counterpart whose name is the same except with an N prefix.