Subject: Re: Looking for a LISP function or macro ...
From: Erik Naggum <>
Date: 1998/09/18
Newsgroups: comp.lang.lisp
Message-ID: <>

* Barry Margolin <>
| Use REMOVE-IF and invert the sense of the test (using the COMPLEMENT
| function, if necessary).  This supercedes the deprecated REMOVE-IF-NOT
| function.

  I find this a conceptually horrible suggestion.  REMOVE-IF-NOT is at
  least possible to deal with as an idiom.  REMOVE-IF of the COMPLEMENT of
  the function I really want in order to _keep_ certain elements is exactly
  how I would have force people to do things if I were into purity for its
  own sake and thought utility and pragmatics were stupid concerns.

  not wanting to deal with the very annoying COMPLEMENT function, I have
  defined functions COLLECT and RETAIN as the semantic complements of
  REMOVE and DELETE, with -IF _and_ -IF-NOT variants.  (COLLECT is a whole
  lot different from REMOVE with some keyword arguments, by the way.)

(defun collect-if (predicate list &rest keys)
  "Return a list of each element from LIST that satisfies PREDICATE.
Accepts the same keyword arguments as REMOVE-IF."
  (apply #'remove-if-not predicate list keys))

  I see no reason at all to deprecate -IF-NOT.  the reason for deprecating
  :TEST-NOT is in a whole different category, since it is unspecified what
  :TEST FOO :TEST-NOT BAR should mean, i.e., when specified at the same
  time, and this problem _does_ come up when applying a function an unknown
  list of keyword-value pairs.  no such thing could ever happen to -IF-NOT
  functions, yet it is apparent from the write-ups that -IF-NOT only got
  deprecated out of some misguided sense of symmetry with :TEST-NOT.

  incidentally, the above function can be written with REMOVE-IF and the
  annoying COMPLEMENT function if one is so inclined.  in any case, I think
  that if you think you need COMPLEMENT, you should define a new function
  that conveys the new purpose, and use that instead.  it may well use
  COMPLEMENT internally.  whether the new function is the test function or
  the caller of the test function depends on the purpose.  the same goes
  for the all the other function-building functions that Dylan has and
  which it's sort of fun to play with, but which I think should not be used
  as open-coded idioms -- better to use them in implementations of
  something that reflects how you think.
  ATTENTION, all abducting aliens!  you DON'T need to RETURN them!