In this file I get 9 warnings of "assumed special". They are
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special in SETQ
;;;*** Warning in CHECK-ROW: RESULT assumed special in SETQ
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special
;;;*** Warning in CHECK-ROW: CHECKARRAY assumed special
;;;*** Warning in CHECK-ROW: RESULT assumed special in SETQ
;;;*** Warning in CHECK-ROW: RESULT assumed special
The whole file is just two functions -
(defun get-element (x y board)
(nth y (nth x board)))
(defun check-row (row board)
(setq checkarray (make-array 9))
(setq result T)
(fill checkarray 0)
(loop for i upto 8 do
(setf (aref checkarray (- (get-element row i board) 1))
(+ (aref checkarray (- (get-element row i board) 1)) 1))
)
(loop for i upto 8 do
(if (or (= (aref checkarray i) 0) (> (aref checkarray i) 1))
(setq result nil) ())
)
result)
I don't get any errors and the functions seem to work fine. So why does it say this? And how can I fix it?
Rainer Joswig's answer is correct in general. In your case, I don't see any need for these variables to be global, so the best thing to do is use let
to make them local to the body of your function:
(defun check-row (row board)
(let ((checkarray (make-array 9)) (result t))
(fill checkarray 0)
(loop for i upto 8 do
(setf (aref checkarray (- (get-element row i board) 1))
(+ (aref checkarray (- (get-element row i board) 1)) 1)))
(loop for i upto 8 do
(if (or (= (aref checkarray i) 0) (> (aref checkarray i) 1))
(setq result nil) ()))
result))
Edit: Also, since you're just adding 1 to a place, you can use incf instead of that long setf:
(defun check-row (row board)
(let ((checkarray (make-array 9)) (result t))
(fill checkarray 0)
(loop for i upto 8 do
(incf (aref checkarray (- (get-element row i board) 1))))
(loop for i upto 8 do
(if (or (= (aref checkarray i) 0) (> (aref checkarray i) 1))
(setq result nil) ()))
result))
Any variable not defined may be assumed to be special. Another interpretation also does not really make sense.
You may either
- introduce your variables as global special variables using DEFVAR or DEFPARAMETER
or
- introduce your variables as local lexical variables using DEFUN, LAMBDA, FLET, LABELS, LET, LET* or others
or
- declare your variables as special or declare the variable reference as special. Usually this is not what one wants.
Anyway, SETQ does not define a or declare a variable. All it does is that it sets an existing variable to some value.
Avoid setting undefined/declared variables with SETQ in code. Its exact consequences are undefined in the ANSI Common Lisp standard.
The difference is that setq is not, strictly speaking, supposed to be used to define a variable (I am not exactly sure why, since it does define a variable).
Use defvar
for globals and the let
construct for locals.
来源:https://stackoverflow.com/questions/3860866/in-lisp-how-do-i-fix-warning-assumed-special