0

Suppose I want to delete one step (element) from the states list.

(defparameter *states* '((:top nil nil) (:subjects nil nil)))
 ;predicate
(defun equal-state? (step state)
  (equal (car step) state))

If I use (delete-if #'equal-state? *states*) then how the second argument ( state) can be passed to predicate?

edited: I have finally found a similar question but I am inclined to retain it because of clarity in the question.

Bilal Qadri
  • 131
  • 11
  • 1
    NB. In this example, you are using DELETE which is authorized to mutate data, but your data is constant (quoted list) and should not be modified in portable programs. – coredump Oct 29 '17 at 13:50

1 Answers1

3
CL-USER 67 > (let ((state :top))
               (delete-if (lambda (step)
                            (equal-state? step state))
                          *states*))
((:SUBJECTS NIL NIL))

or

CL-USER 68 > (defun make-predicate (state)
               (lambda (step)
                 (equal-state? step state)))
MAKE-PREDICATE

CL-USER 69 > (delete-if (make-predicate :subjects)
                        *states*)
((:TOP NIL NIL))

As user coredump mentions, delete-if is a potentially destructive operation. The non-destructive alternative to delete-if is remove-if.

One can also use remove/ delete:

CL-USER 77 > (remove :subjects
                     '((:top nil nil)
                       (:subjects nil nil))
                     :key #'first
                     :test #'equal)
((:TOP NIL NIL))
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • @coredump intimated that constant data should not be modified in portable programs ... my lisp implementation also warns me about the constant data .. I just can't wrap my head around it .. and "constant data in portable programs?" – Bilal Qadri Oct 29 '17 at 16:23
  • 1
    @BilalQadri: if you have `'(a b c)` written in your program, it is a quoted list. This list is literal data. It is unspecified what happens if you modify it. Could work, could have side effects, could silently fail, could cause an error. Unspecified. A fresh list will be created with functions like LIST, COPY-LIST and many others. If you type a literal list to REPL there is some good chance that you can modify it without seeing problems, but generally this is not the case. Especially in compiled code it is likely to cause problems. That's not Lisp specific. Other langs have similar problems. – Rainer Joswig Oct 29 '17 at 16:30