Skip to content

Commit

Permalink
Add DEFACCESSOR per issue #47
Browse files Browse the repository at this point in the history
This version of DEFACCESSOR differs from the GitHub suggestion in that
it allows an arbitrary place to be identified for the generated
SETF function.
  • Loading branch information
stylewarning committed Dec 24, 2015
1 parent 5492e22 commit d5ec38b
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions quickutil-utilities/utilities/language.lisp
Expand Up @@ -66,3 +66,49 @@
`(let ((,var ,val))
,@body))
%%%)

(defutil defaccessor (:version (1 . 0)
:depends-on (parse-body with-gensyms)
:provides (defaccessor accesses)
:category language)
"Define the function named `name` just as with a normal `defun`. Also define the setter `(setf name)`. The form to be set (i.e., the place) should be wrapped in the local macro `accesses`. For example,
```
CL-USER> (let ((x 0))
(defaccessor saved-x ()
(accesses x)))
SAVED-X
(SETF SAVED-X)
CL-USER> (saved-x)
0
CL-USER> (setf (saved-x) 5)
5
CL-USER> (saved-x)
5
```
"
#>%%%>
(defmacro defaccessor (name lambda-list &body body)
%%DOC
(multiple-value-bind (remaining-forms decls doc)
(parse-body body :documentation t)
(with-gensyms (new-value)
`(progn
(defun ,name ,lambda-list
,doc
,@decls
(macrolet ((accesses (form)
form))
,@remaining-forms))

(defun (setf ,name) ,(cons new-value lambda-list)
,(format nil "Setter for the function ~S." name)
,@decls
(macrolet ((accesses (form)
`(setf ,form ,',new-value)))
,@remaining-forms
,new-value))
(values
',name
'(setf ,name))))))
%%%)

0 comments on commit d5ec38b

Please sign in to comment.