Subject: bug#76017: 31.0.50; Which args can cl-nintersection and cl-nset-difference mutate?

From: "Basil L. Contovounesios" <[email-masked]>
Date: Sun, 02 Feb 2025 18:48:40 +0100

Since as far back as I can go in emacs.git history, the manual says:

 -- Function: cl-nintersection list1 list2 &key :test :test-not :key
     This is a destructive version of ‘cl-intersection’.  It tries to
     reuse storage of LIST1 rather than copying.  It does _not_ reuse
     the storage of LIST2.

 -- Function: cl-nset-difference list1 list2 &key :test :test-not :key
     This is a destructive ‘cl-set-difference’, which will try to reuse
     LIST1 if possible.

whereas their docstrings say:

 (cl-nintersection LIST1 LIST2 [KEYWORD VALUE]...)
 Combine LIST1 and LIST2 using a set-intersection operation.
 The resulting list contains all items that appear in both LIST1 and LIST2.
 This is a destructive function; it reuses the storage of LIST1 and LIST2
 whenever possible.

 (cl-nset-difference LIST1 LIST2 [KEYWORD VALUE]...)
 Combine LIST1 and LIST2 using a set-difference operation.
 The resulting list contains all items that appear in LIST1 but not LIST2.
 This is a destructive function; it reuses the storage of LIST1 and LIST2
 whenever possible.

The mutates-arguments property added in

 Byte-compiler warning about mutation of constant values
 bfc07100d28 2023-05-13 11:53:25 +0200
 https://git.sv.gnu.org/cgit/emacs.git/commit/?id=bfc07100d28

agrees with the docstrings, but CL docs I found online, and João's patch
in https://lists.gnu.org/r/emacs-devel/2023-11/msg00595.html agree with
the manual.

My arguments in favour of the manual:
- Documented for decades in both Emacs and CL docs.
- It is the weaker of the two requirements, thus backward-compatible.
- Set difference implementations do not naturally benefit from modifying
  the second set (though I would love to see a counterexample).
- Callers of cl-nintersection having to ensure both arguments are safe
  to mutate (e.g. through excessive copying) could diminish any
  performance benefit it has over cl-intersection.

If there is agreement, I can follow up with a patch for our docs and
tests.

Thanks,
-- 
Basil

In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.18.2, Xaw3d scroll bars) of 2025-02-02 built on tais
Repository revision: c91c591f0f0cc774647c32bdcf05bb3a9551e340
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12101015
System Description: Debian GNU/Linux trixie/sid