Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Common Lisp aref behavior

I don't understand why setf will not work with an array reference returned from a function call. In the below example, why does the final call fail?

(setf arr #1a(a b c))

(defun ret-aref (a i)
    (aref a i))

(eql (ret-aref arr 0) (aref arr 0))

;succeeds
(progn
    (setf (aref arr 0) 'foo)
    arr)

;fails
(progn
    (setf (ret-aref arr 0) 'bar)
    arr)
like image 520
RunicMachine Avatar asked Jan 15 '23 17:01

RunicMachine


1 Answers

The setf operator is actually a macro, which needs to be able to inspect the place-form already at compile time. It has special knowledge about aref, but doesn't know anything about your ret-aref.

The easiest way to make your function known to setf is by defining a suitable setf-function companion for it. Example:

(defun (setf ret-aref) (new-value array index) 
   (setf (aref array index) new-value))

Now, (setf (ret-aref arr 0) 'bar) should work.

This simple example hides the fact, that setf-expansion is actually a pretty hairy topic. You can find the gory details in the CLHS.

like image 163
Dirk Avatar answered Feb 01 '23 11:02

Dirk