Reputation: 13
I have a list with cons-pairs, e.g. '((a . 3) (b . 2))
. I want to remove a cons-pair destructive if the first element in the cons-pair matches var. My function cannot remove the cons-pair if there is only one cons-pair in the list or if it is first in the list.
(defun delete-bindings! (var symbol-table)
(cond
((endp symbol-table) '())
((eql var (caar symbol-table))
(delete-bindings! var (cdr symbol-table)))
(t (setf (cdr symbol-table) (delete-bindings! var (cdr symbol-table)))
symbol-table))))
What am I missing?
Thanks!
Upvotes: 1
Views: 4601
Reputation: 41170
Your function is always returning '()
, I think (can't be sure since you didn't show the whole thing).
Perhaps:
(defun delete-bindings! (var symbol-table)
(cond
((endp symbol-table) '())
((eql var (caar symbol-table))
(delete-bindings! var (cdr symbol-table)))
(t (progn
(setf (cdr symbol-table) (delete-bindings! var (cdr symbol-table)))
symbol-table)))
Addendum:
You must use the result of this function, not simply depend on its side effects:
(setq *bindings* (delete-bindings! 'var *bindings*))
Second addendum
Loading ~/ccl-init.lisp
Welcome to Clozure Common Lisp Version 1.7-dev-r14406M-trunk (DarwinX8632)!
? (defun delete-bindings! (var symbol-table)
(cond
((endp symbol-table) '())
((eql var (caar symbol-table))
(delete-bindings! var (cdr symbol-table)))
(t (progn
(setf (cdr symbol-table) (delete-bindings! var (cdr symbol-table)))
symbol-table))))
DELETE-BINDINGS!
? (delete-bindings! 'a '((a . 3) (b . 2)))
((B . 2))
?
If you need a data structure that may be destructively modified with all references to it updated, you'll need another level of indirection.
E.g.,
(defvar *symbol-table* (cons 'bindings '((a . 3) (b . 2))))
(defun delete-bindings! (var symbol-table)
(flet ((db! (var symbol-table) (cond
((endp symbol-table) '())
((eql var (caar symbol-table))
(delete-bindings! var (cdr symbol-table)))
(t (progn
(setf (cdr symbol-table) (delete-bindings! var (cdr symbol-table)))
symbol-table)))))
(rplacd symbol-table (db! var (cdr symbol-table)))))
Upvotes: 2
Reputation: 6681
Functions cannot modify a variable that they get as argument, they always receive the variable's value instead of the variable itself. Instead, you can use DEFINE-MODIFY-MACRO:
(define-modify-macro delete-bindings! (item)
(lambda (symbol-table item)
(remove item symbol-table :key #'car)))
Upvotes: 1