pop puzzle

Discussion of Common Lisp
Post Reply
dynamic
Posts: 2
Joined: Tue Sep 13, 2011 1:39 pm

pop puzzle

Post by dynamic » Wed Sep 14, 2011 2:51 pm

Hello Lispers!

It is usually said that (pop stack) is equivalent of (prog1 (first stack) (setf stack (rest stack))) or (let ((elt (first stack))) (setf stack (rest stack)) elt). I don't understand why the following function doesn't work as an equivalent of built-in pop:

Code: Select all

(defun my-pop (lst)
  (let ((x (first lst)))
    (setf lst (rest lst))
    x))
Example:

Code: Select all

? (setf lstA '(a b c))
? (my-pop lstB)
A
? lstA
(A B C)
? (setf lstB '(a b c))
? (pop lstB)
A
? lstB
(B C)
But:
? (setf lstC '(a b c))
? (let ((x (car lstC)))
    (setf lstC (cdr lstC))
    x)
A
? lstC
(B C)
:?:
Last edited by dynamic on Fri Sep 16, 2011 9:52 am, edited 1 time in total.

nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: pop puzzle

Post by nuntius » Wed Sep 14, 2011 8:37 pm

Your setf is modifying a local variable, not the original structure. There are ways of destructively modifying a list in-place (edit the car and cdr of the cons cells); but a lot of lisp code assumes cons cells are immutable (not enforceable in CL).

Read about defsetf and define-setf-expander. If you want to modify something in-place, macros are the way to go.

dynamic
Posts: 2
Joined: Tue Sep 13, 2011 1:39 pm

Re: pop puzzle

Post by dynamic » Thu Sep 15, 2011 2:47 am

Thank you for your answer and pointers to defsetf and define-setf-expander. I will study it.

Post Reply