REMF-MULTIPLEREMF and REMPROP are not explicit about what happens in the case that a duplicated indicator occurs on the plist. One or both indicators might be removed.REMF and REMPROP at most one indicator/value pair from the designated plist.REMF and REMPROP remove all matching indicator/value pairs from the designated plist.REMF and REMPROP is not well-defined, iterating to remove more than one property is expensive because you have to start over from the head of the list.REMF or any other function that takes a property list (including GETF); it "is an error" for a symbol to have duplicated properties on its property list.The only thing that CLtL pp 163-167 says about duplicated indicators on plists is that there aren't any (first line on page 164). It does not even gurantee that GETF returns the first occurrence.
;; Case #1 - removing symbol properties,etc. using REMPROP
(DEFUN REMF-MULTIPLE-TEST-1 () (LET ((SYMBOL (GENSYM))) (SETF (SYMBOL-PLIST SYMBOL) (LIST 'A 'B 'C 'D 'A 'B 'C 'D)) (FORMAT T "~&Before: ~S~%" (SYMBOL-PLIST SYMBOL)) (REMPROP SYMBOL 'A) (FORMAT T "~&After: ~S~%" (SYMBOL-PLIST SYMBOL)) (FORMAT T "~&This implementation uses REMF-MULTIPLE:~:[REMOVE-ALL~;REMOVE-ONE~] ~ for REMPROP.~%" (GET SYMBOL 'A))))
;; Case #2 - removing keywords,etc. using REMF
(DEFUN REMF-MULTIPLE-TEST-2 () (LABELS ((HELPER (&REST ARGUMENTS &KEY (A 1) (B 2)) (FORMAT T "~&Helper received: ~S~%" ARGUMENTS) (LIST A B)) (DRIVER (&REST ARGUMENTS) (FORMAT T "~&Helper received: ~S~%" ARGUMENTS) (SETQ ARGUMENTS (COPY-LIST ARGUMENTS)) (REMF ARGUMENTS ':A) (APPLY #'HELPER ARGUMENTS))) (LET ((RESULT (DRIVER :A 3 :B 4 :A 5 :B 6))) (FORMAT T "~&Returned: ~S~%" RESULT) (FORMAT T "~&This implementation uses REMF-MULTIPLE:~:[REMOVE-ALL~;REMOVE-ONE~] ~ for REMF.~%" (= (CAR RESULT) 5)))))
REMF-MULTIPLE:REMOVE-ONE.REMPROP and/or REMF in microcode might have a slightly harder time, but any change should still be very localized.IS-ERROR at least makes the situation more explicit. For the other proposals, users who want to use REMPROP or REMF in situations which involve lists that might have duplicated elements would be able to do so more reliably.
Pitman is agnostic on this for now. There are advantages to both. If everybody already implements REMOVE-ONE, that would seem the way to go.
"If we're going to extend Common Lisp to allow duplicated indicators on plists, we should do it for all the property list functions, not just REMF and REMPROP."