Discussion:
Defined but no used variable warning during setf expansion
Burton Samograd
2012-01-23 13:18:16 UTC
Permalink
Content preview: Hello, I am wondering if anyone can explain the reason for
the defined but not used variable in setf that this code is experiencing:
CL-USER> (set-macro-character #\$ (lambda (stream char) (declare (ignore
char)) (let ((v (read stream))) (list (get v 'setf-handler-name) v)))) [...]


Content analysis details: (-0.7 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low
trust
[209.85.161.179 listed in list.dnswl.org]
0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider
(burton.samograd[at]gmail.com)
-0.0 SPF_PASS SPF: sender matches SPF record
0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/607>

Hello,

I am wondering if anyone can explain the reason for the defined
but not used variable in setf that this code is experiencing:

CL-USER> (set-macro-character #\$
(lambda (stream char)
(declare (ignore char))
(let ((v (read stream)))
(list (get v 'setf-handler-name) v))))

(defmacro defactive (var value &key write-handler read-handler)
(let ((setf-handler-name (gensym)))
`(progn
(defparameter ,var ,value)
(defmacro ,setf-handler-name (,var)
(let ((read-handler (gensym)))
`(let ((,read-handler (get ',',var :read-handler)))
(if ,read-handler
(funcall ,read-handler (eval ,',var))
,',var))))
(defsetf ,setf-handler-name (,var) (new-val)
(let ((write-handler (gensym)))
`(let ((,write-handler (get ',',var :write-handler)))
(when ,write-handler
(funcall ,write-handler (eval ,',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 (random 6)
:read-handler (lambda (val) (let ((old val)) (setf d6 (random 6)) old)))

STYLE-WARNING: redefining COMMON-LISP-USER::DEFACTIVE in DEFMACRO
STYLE-WARNING: redefining COMMON-LISP-USER::SETACTIVE in DEFMACRO
1
CL-USER> (setf $x 10)
; in: SETF (#:G1129 X)
; (LET* ((#:G1175 X))
; (MULTIPLE-VALUE-BIND (#:G1176)
; 10
; (LET ((#:G1177 #))
; (WHEN #:G1177 (FUNCALL #:G1177 # #:G1176))
; (SETF X #:G1176))))
;
; caught STYLE-WARNING:
; The variable #:G1175 is defined but never used.
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
old: 0 new: 10
10

--
Burton Samograd
http://kruhft.dyndns.org
Sam Steingold
2012-01-23 17:57:06 UTC
Permalink
Content preview: > * Burton Samograd <ohegba.fnzbtenq-***@public.gmane.org> [2012-01-23
06:18:16 -0700]: > > ; caught STYLE-WARNING: > ; The variable #:G1175 is
defined but never used. I think this is a compiler bug: "defined but never
used" warnings should only be signaled for interned symbols, not gensyms.
Macros often define gensyms which might not be used by some macro uses. [...]


Content analysis details: (-100.7 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low
trust
[209.85.216.44 listed in list.dnswl.org]
-100 USER_IN_WHITELIST From: address is in the user's white-list
0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider
(sam.steingold[at]gmail.com)
-0.0 SPF_PASS SPF: sender matches SPF record
0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/608>
Post by Burton Samograd
; The variable #:G1175 is defined but never used.
I think this is a compiler bug: "defined but never used" warnings should
only be signaled for interned symbols, not gensyms.
Macros often define gensyms which might not be used by some macro uses.
--
Sam Steingold (http://sds.podval.org/) on Ubuntu 11.10 (oneiric) X 11.0.11004000
http://palestinefacts.org http://mideasttruth.com http://dhimmi.com
http://openvotingconsortium.org http://www.PetitionOnline.com/tap12009/
If a train station is a place where a train stops, what's a workstation?
Scott L. Burson
2012-01-23 23:37:03 UTC
Permalink
Content preview: On Mon, Jan 23, 2012 at 5:18 AM, Burton Samograd <burton.samograd-***@public.gmane.org>
wrote: > Hello, > > I am wondering if anyone can explain the reason for the
defined > but not used variable in setf that this code is experiencing: [...]


Content analysis details: (-100.7 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low
trust
[209.85.212.51 listed in list.dnswl.org]
-100 USER_IN_WHITELIST From: address is in the user's white-list
-0.0 SPF_PASS SPF: sender matches SPF record
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/609>

On Mon, Jan 23, 2012 at 5:18 AM, Burton Samograd
Post by Burton Samograd
Hello,
I am wondering if anyone can explain the reason for the defined
I don't know for sure, but there are a couple of things that are odd
about your macro-writing macro. One is that in the `defmacro' and
`defsetf' it generates, the `var' passed in the outer macro call is
reused as a parameter of the generated macro and setf expander. The
other is the two calls to `eval'.

I haven't taken the time to work out why those things are there, but I
would suggest they probably shouldn't be. Try getting rid of them and
see what happens.

-- Scott
Post by Burton Samograd
(defmacro defactive (var value &key write-handler read-handler)
 (let ((setf-handler-name (gensym)))
  `(progn
     (defparameter ,var ,value)
     (defmacro ,setf-handler-name (,var)
       (let ((read-handler (gensym)))
         `(let ((,read-handler (get ',',var :read-handler)))
            (if ,read-handler
                (funcall ,read-handler (eval ,',var))
                ,',var))))
     (defsetf ,setf-handler-name (,var) (new-val)
       (let ((write-handler (gensym)))
         `(let ((,write-handler (get ',',var :write-handler)))
            (when ,write-handler
              (funcall ,write-handler (eval ,',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)))
Pascal J. Bourguignon
2012-01-24 06:04:43 UTC
Permalink
Content preview: Burton Samograd <burton.samograd-***@public.gmane.org> writes: > CL-USER>
(setf $x 10) > ; in: SETF (#:G1129 X) > ; (LET* ((#:G1175 X)) > ; (MULTIPLE-VALUE-BIND
(#:G1176) > ; 10 > ; (LET ((#:G1177 #)) > ; (WHEN #:G1177 (FUNCALL #:G1177
# #:G1176)) > ; (SETF X #:G1176)))) > ; > ; caught STYLE-WARNING: > ; The
variable #:G1175 is defined but never used. [...]

Content analysis details: (-0.0 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay
domain
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/610>
Post by Burton Samograd
CL-USER> (setf $x 10)
; in: SETF (#:G1129 X)
; (LET* ((#:G1175 X))
; (MULTIPLE-VALUE-BIND (#:G1176)
; 10
; (LET ((#:G1177 #))
; (WHEN #:G1177 (FUNCALL #:G1177 # #:G1176))
; (SETF X #:G1176))))
;
; The variable #:G1175 is defined but never used.
I don't think it's a compiler error (there's no reason to treat
uninterned symbols differently from interned ones).


Clearly, there's a single occurence of #:G1175, in the binding of the
LET* form, and no use of it. You should either avoid generating it, or
add a

(declare (ignorable #:G1175))

expression before the body of the LET*.
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Martin Simmons
2012-01-24 18:51:49 UTC
Permalink
Content preview: >>>>> On Tue, 24 Jan 2012 07:04:43 +0100, Pascal J Bourguignon
said: > > Burton Samograd <burton.samograd-***@public.gmane.org> writes: > > > CL-USER>
(setf $x 10) > > ; in: SETF (#:G1129 X) > > ; (LET* ((#:G1175 X)) > > ; (MULTIPLE-VALUE-BIND
(#:G1176) > > ; 10 > > ; (LET ((#:G1177 #)) > > ; (WHEN #:G1177 (FUNCALL
Post by Pascal J. Bourguignon
; The variable #:G1175 is defined but never used. > > > I don't think
it's a compiler error (there's no reason to treat > uninterned symbols differently
from interned ones). > > > Clearly, there's a single occurence of #:G1175,
in the binding of the > LET* form, and no use of it. You should either avoid
generating it, or > add a > > (declare (ignorable #:G1175)) > > expression
before the body of the LET*. [...]

Content analysis details: (-0.0 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay
domain
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/611>
Post by Pascal J. Bourguignon
CL-USER> (setf $x 10)
; in: SETF (#:G1129 X)
; (LET* ((#:G1175 X))
; (MULTIPLE-VALUE-BIND (#:G1176)
; 10
; (LET ((#:G1177 #))
; (WHEN #:G1177 (FUNCALL #:G1177 # #:G1176))
; (SETF X #:G1176))))
;
; The variable #:G1175 is defined but never used.
I don't think it's a compiler error (there's no reason to treat
uninterned symbols differently from interned ones).
Clearly, there's a single occurence of #:G1175, in the binding of the
LET* form, and no use of it. You should either avoid generating it, or
add a
(declare (ignorable #:G1175))
expression before the body of the LET*.
Unfortunately neither of those solutions are possible directly, because the
binding is generated by the SETF macro.

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.
--
Martin Simmons
LispWorks Ltd
http://www.lispworks.com/
Burton Samograd
2012-01-24 19:30:56 UTC
Permalink
Content preview: On Tue, Jan 24, 2012 at 11:51 AM, Martin Simmons 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.
[...]

Content analysis details: (-0.7 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low
trust
[209.85.161.179 listed in list.dnswl.org]
0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider
(burton.samograd[at]gmail.com)
-0.0 SPF_PASS SPF: sender matches SPF record
0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid
Archived-At: <http://permalink.gmane.org/gmane.lisp.cl-pro/612>
Post by Martin Simmons
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

Loading...