pjstirling wrote:...
I consider using SETQ at toplevel to create "global" variables evil (as compared to using DEFVAR or DEFPARAMETER), and I'm not alone, sbcl will complain if you do it.
...
Many implementations won't complain before you actually try to compile it. The implementations are free to choose how it should be treated but most will interpret it as if it was declared special. That means `setq` and `defparameter` are interchangable in those implementations except for the warnings.
Code: Select all
(setq name-without-earmuffs 0)
(defun increase (&optional (step 1))
(setq name-without-earmuffs (+ step name-without-earmuffs)))
I save this as test.cl. Now lets see what happens in CLISP:
Code: Select all
(load "test.cl") ; no errors
(increase) ; 1
(compile 'increase) ; lots of warnings
; WARNING: in INCREASE : NAME-WITHOUT-EARMUFFS is neither declared nor bound,
; it will be treated as if it were declared SPECIAL.
(compile-file "test.cl") ; lots of warnings
;; Compiling file test.cl ...
;WARNING: in #:|1 1 (SETQ NAME-WITHOUT-EARMUFFS 10)-1| in line 1 : NAME-WITHOUT-EARMUFFS is neither declared nor bound,
; it will be treated as if it were declared SPECIAL.
;WARNING: in INCREASE in lines 2..3 : NAME-WITHOUT-EARMUFFS is neither declared nor bound,
; it will be treated as if it were declared SPECIAL.
;WARNING: in INCREASE in lines 2..3 : NAME-WITHOUT-EARMUFFS is neither declared nor bound,
; it will be treated as if it were declared SPECIAL.
;; Wrote file test.fas
;The following special variables were not defined:
; NAME-WITHOUT-EARMUFFS
;0 errors, 3 warnings
Just adding one line to the top of the file and perhaps adhering to the naming convention and you don't get these:
Code: Select all
;; the two lines below can be replaced with one defparameter
(declaim (special *name-with-earmuffs*))
(setq *name-with-earmuffs* 0)
(defun increase (&optional (step 1))
(setq *name-with-earmuffs* (+ step *name-with-earmuffs*)))
Now, since it's special it's obvious you know they're not lexical and thus the warnings don't show up.
However in my example where we are counting number of applications it might be better to use defvar since consecutive loading don't reset the value.