I am writing a program in Common Lisp which needs to store a bunch of status bits for a very large number of entries in an array (the whole program is pretty much fortran-in-lisp) and the status bits are encoded as bits in a fixnum sitting in this array. The accessors for these status bits are actually going to be defined by a macro so I don't have to care about allocating the bits, but a sample reader function might be
(defun deadp (e)
(logbitp 0 e))
(In real life this will be inlined and cluttered with declarations to try and make sure it's quick but those don't matter here I think.)
I need these things to be functions because I want to be able to map them, but also because the using-a-macro-to-inline-a-function thing makes me feel bad.
Then I'll be using this as something like this:
(defconstant status-index 3)
...
(dotimes (i nentries)
(unless (deadp (aref entries i status-index))
...))
(In real life (aref entries i status-index) will be (status entries i), which in turn is going to need a setf method but I think that's easy.)
or
(loop for i below nentries
counting (if (deadp entries i status-index) 1 0))
And of course there will be other similar single-bit flags which will have different bits associated with them.
So, now I want to be able to do this:
(dotimes (i nentries)
...
(when ...
(setf (deadp (aref entries i status-index) t)))
...)
which should turn into code equivalent to
(dotimes (i nentries)
...
(when ...
(progn
(setf (ldb (byte 1 0) (aref entries i status-index)) 1)
t))
...)
And also this:
(let ((status 0))
...
(when ...
(setf (deadp status) t))
...)
which should turn into code equivalent to this:
(let ((status 0))
...
(when ...
(progn
(setf (ldb (byte 1 0) status) 1)
t))
...)
In other words I want my deadp function to be an accessor and for setf on it to work in a general way for it: (setf (deadp (cdr x)) nil) should work, etc.
So this has dropped me into bits of CL that I've avoided for a long time: defining setf expanders. Pretty obviously just defining a (setf deadp) function won't work because numbers are immutable, and I'm fairly sure that defsetf is not powerful enough, so I need define-setf-expander, which I don't understand.
Can someone explain how I need to do this? I think the particular deadp function is not critical, although all the functions I care about will look like variants of it.
An alternative answer would be 'that's a braindead approach, instead do ...', and I'm open to those. I have considered writing code which abstracts the array away, so instead of (deadp (aref ...)) I'd write (deadp people ...) where people is the array of people. This would be fine, and it's easy to see how to make that setfable, except I also want to be able to say (deadp status) where status is just a fixnum. But perhaps there is some better approach.