I understand the conceptual elegance of linear-update procedures, but the trade-off is they're slightly inconvenient and hard to use safely. Which may be why no-one except the Scheme community (as far as I know) uses them.
CL's list-modifying procedures are also linear-update. This is necessary, because the value to be modified may be (). Thus it allows NREVERSE to be implemented as REVERSE. The same applies to the p-list functions, DELETE, DELETE-DUPLICATES, and the lists-as-sets functions. See <http://clhs.lisp.se/Issues/iss293_w.htm
> for details.
NCONC (append!) is an exception, because it simply ignores any () arguments, so it is guaranteed to use mutation. NSUBSTITUTE, which replaces an element equal to its old-object argument with its new-object argument, is also guaranteed to mutate its sequence (list or vector) argument.
Thanks. I have mixed feelings about this.
If you prefer me to remove your name altogether, I can with your permission.
P.S.: It would be a great change to all the existing linear update procedures in R7RS-large, but one could reconsider the choice of `!' as the marker of such a linear update procedure. It may look too similar to the use of `!' in `set!' and traditional procedures that are called just for there side effect.
I have a pre-pre-SRFI for a "list surgery" library, a subset of SRFI 1, that guarantees that modifiable arguments actually are modified unless they are (). Tentatively I am marking the procedures with "!!", although it is of course too late to go back and fix up existing names.
There will also be (list-replace!! last-dst first-dst first-src last-src), which replaces the cdr of last-dst with first-src and the cdr of last-src with first-dst. It is an error if first-dst is not the cd..dr of last-dst or last-src is not the cd...dr of first-src. If the underlying destination is '(a b c d e f), last-dst is (d e f) and first-dst is (f), the underlying source is (w x y z), first-src is (x y z), and last-src is (), then the destination string is (a b c x y z f).