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:

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.