jscl icon indicating copy to clipboard operation
jscl copied to clipboard

setf doesn't work with first or elt

Open eudoxia0 opened this issue 10 years ago • 1 comments

CL-USER> (let ((list (list 1 2 3))) (setf (car list) 0) list)
(0 2 3)
CL-USER> (let ((list (list 1 2 3))) (setf (first list) 0) list)
ERROR: Unknown generalized reference.
CL-USER> (let ((vec (vector 1 2 3))) (setf (aref vec 0) 0) vec)
#(0 2 3)
CL-USER> (let ((vec (vector 1 2 3))) (setf (elt vec 0) 0) vec)
ERROR: Unknown generalized reference.

I think SETF expansion might require a bit more than macroexpanding the place.

eudoxia0 avatar Apr 19 '15 16:04 eudoxia0

It should be easy. It is just a setf on the car or cdr of a c[d]*r.

But we are missing the easy ways to define setf expanders. Right now only define-setf-expander is available. It would be great if we could implement defsetf and (defun (setf fn) ...) before.

davazp avatar Apr 20 '15 08:04 davazp

Is there any workarounds?

I am facing similar problem:

CL-USER> (defparameter *enemy-list* (list (list 1 200) (list 2 100) (list 3 0) (list 4 -100) (list 5 -200)))
*ENEMY-LIST*
CL-USER> (nth 3 *enemy-list*)
(4 -100)
CL-USER> (cadr (nth 3 *enemy-list*))
-100
CL-USER> (incf (cadr (nth 3 *enemy-list*)))
ERROR: Unknown generalized reference.
CL-USER> (setf (cadr (nth 3 *enemy-list*)) 1)
ERROR: Unknown generalized reference.

But I can't get it through (yet).

VitoVan avatar Apr 28 '23 10:04 VitoVan

before this issue were closed, we have to rewrite our code like this:

(incf x) ≡ (incf x 1) ≡ (setf x (+ x 1))
(decf x) ≡ (decf x 1) ≡ (setf x (- x 1))

as in PAIP chapter 3.2

VitoVan avatar May 12 '23 02:05 VitoVan

Ah, this one is indeed easy, all we need is something like:

(define-setf-expander cadr (x)
  (get-setf-expansion `(car (cdr ,x))))

I'm gonna implement this.

May be I could close this 8 years old issue.

VitoVan avatar May 12 '23 03:05 VitoVan