[pro] Defined but no used variable warning during setf expansion
Burton Samograd
burton.samograd at gmail.com
Tue Jan 24 19:30:56 UTC 2012
On Tue, Jan 24, 2012 at 11:51 AM, Martin Simmons <martin at lispworks.com> wrote:
> The binding is there because the reader macro expansion passes X as an
> argument, as in (#:G1129 X). The setf expander is defined using DEFSETF, so
> it has to evaluate all of its arguments in left-to-right order by binding them
> to temporary variables.
>
> It isn't clear to me why this argument is needed, because the DEFSETF form can
> access the variable directly.
>
> OTOH, the uses of EVAL look strange and I suspect the whole thing could be
> written more clearly without needing a separate DEFMACRO and DEFSETF for each
> DEFACTIVE form. That approach would need to use DEFINE-SETF-EXPANDER instead
> of DEFSETF.
Thank you all for your input on this problem. I have reworked the
code to remove the eval's (for some reason I thought they were
needed). I also removed the parameter to the setf-handler, I guess I
thought that you needed a parameter to the setf handler and didn't
realize that the variable binding was already there. This was really
just a thought experiment in macro programming to implement a feature
of ksh, and as always, I am just learning. Here is the reworked code:
(set-macro-character #\$
(lambda (stream char)
(declare (ignore char))
(let ((v (read stream)))
(list (get v 'setf-handler-name)))))
(defmacro defactive (var value &key write-handler read-handler)
(let ((setf-handler-name (gensym)))
`(progn
(defparameter ,var ,value)
(defmacro ,setf-handler-name ()
(let ((read-handler (gensym)))
`(let ((,read-handler (get ',',var :read-handler)))
(if ,read-handler
(funcall ,read-handler ,',var)
,',var))))
(defsetf ,setf-handler-name () (new-val)
(let ((write-handler (gensym)))
`(let ((,write-handler (get ',',var :write-handler)))
(when ,write-handler
(funcall ,write-handler ,',var ,new-val))
(setf ,',var ,new-val))))
(setf (get ',var 'setf-handler-name) ',setf-handler-name)
(setf (get ',var :write-handler) ,write-handler)
(setf (get ',var :read-handler) ,read-handler)
,value)))
(defmacro setactive (var &key read-handler write-handler)
`(progn
(when ,read-handler
(setf (get ',var :read-handler) ,read-handler))
(when ,write-handler
(setf (get ',var :write-handler) ,write-handler))))
(defactive x 0
:write-handler (lambda (old-val new-val) (format t "old: ~A new: ~A"
old-val new-val))
:read-handler (lambda (val) (format t "value: ~A" val) val))
;(setactive x :read-handler (lambda (val) (format t "~A !!! ~A" val)))
;(setactive x :write-handler (lambda (old-val new-val) (format t "~A
!!! ~A" old-val new-val)))
(defactive d6 (1+ (random 6))
:read-handler (lambda (val) (let ((old val)) (setf d6 (1+ (random 6))) old)))
I will look into understanding define-setf-expander to see how this
could be improved. I'm just happy that it works and I could implement
it at all...long live user programmable languages!
--
Burton Samograd
http://kruhft.dyndns.org
More information about the pro
mailing list