(defun (setf foo) (val arg) ...)


#1

Common Lisp has this:

CL-USER> (defun foo (arg)
           (format t "foo getter called arg=~a~%" arg)
           'foo-value)
FOO
CL-USER> (defun (setf foo) (val arg)
           (format t "foo setter called val=~a arg=~a~%" val arg))
(SETF FOO)
CL-USER> (setf (foo (foo 'arg)) 'new-val)
foo getter called arg=ARG
foo setter called val=NEW-VAL arg=FOO-VALUE
NIL

I don’t think this would be difficult to implement.

Currently defun and defvar will error if you give it a cons as as the function name so this would have to be removed. pprintall already will get it printed properly as far as I can tell.

As for setf, I think that implementing it would only involve one thing: now that globals can contain cons pairs (setf <function-name>) as keys, before place() throws the “invalid place” error, it can just check if the place (after evaluating the arguments) is equal to any key in the current env, and if it is, call the function and return NULL so that sp_setf() will know that it has been handled (and shouldn’t dereference a null pointer).

I might get around to implementing this. If I do I will share it here.


#2

I have now implemented this in f4cd15cb2231267f92c9229eadfc80eb0ed7790b!

> (defun foo (arg)
    (format t "foo getter called arg=~a~%" arg)
    'foo-value)
foo

> (defun (setf foo) (val arg)
    (format t "foo setter called val=~a arg=~a~%" val arg)
    'foo-setter-value)
(setf foo)

> (setf (foo (foo (foo 'arg))) 'new-val)
foo getter called arg=arg
foo getter called arg=foo-value
foo setter called val=new-val arg=foo-value
foo-setter-value