Some iteration forms don't honor the principle that iteration variables are, by definition, always "used".
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Low
|
Douglas Katzman |
Bug Description
What I do:
(do (var) (t))
(do* (var) (t))
(do-all-symbols (var))
(do-external-
(do-symbols (var))
(dolist (var '(1 2 3)))
What happens:
In all these cases, a STYLE-WARNING is signaled:
"The variable VAR is defined but never used."
What I expected to happen:
The standard states, in the section for Declaration IGNORE:
"The stream variables established by with-open-file, with-open-stream, with-input-
Glossary entry for "iteration variable": "n. a variable V, the binding for which was created by an explicit use of V in an iteration form."
Glossary entry for "iteration form": "n. a compound form whose operator is named in the next figure, or a compound form that has an implementation-
do do-external-symbols dotimes
do* do-symbols loop
do-all-symbols dolist"
These STYLE-WARNINGs thus seem to be spurious (as silly as the examples may be).
DOTIMES is not affected by this bug. LOOP doesn't seem to be either, though I only tried one trivial example.
The forms establishing stream variables are not affected by this bug.
SBCL version: 1.0.42
uname -a: Linux dynamorph 2.6.32-27-generic #49-Ubuntu SMP Wed Dec 1 23:52:12 UTC 2010 i686 GNU/Linux
*features*:
(:SWANK :QUICKLISP :SB-BSD-
:SBCL :SB-DOC :SB-TEST :SB-LDB :SB-PACKAGE-LOCKS :SB-UNICODE :SB-EVAL
:SB-SOURCE-
:LARGEFILE :GENCGC :STACK-
:COMPARE-
:STACK-
:STACK-
:CYCLE-COUNTER :INLINE-CONSTANTS :MEMORY-
:OS-PROVIDES-
Changed in sbcl: | |
importance: | Undecided → Low |
status: | New → Triaged |
Changed in sbcl: | |
assignee: | Roman Marynchak (roman-marynchak) → nobody |
Changed in sbcl: | |
status: | In Progress → Confirmed |
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
* (macroexpand '(dolist (v '(1 2 3))))
(BLOCK NIL
(TAGBODY) )
(LET ((#:N-LIST609 '(1 2 3)))
(TAGBODY
#:START610
(UNLESS (ENDP #:N-LIST609)
(LET* ((#:TMP611 (TRULY-THE (MEMBER 3 2 1) (CAR #:N-LIST609)))
(V #:TMP611))
(SETQ #:N-LIST609 (CDR #:N-LIST609))
(GO #:START610))))
NIL)
This is very interesting. How can we make V to be "used" without the knowledge about the origin of the expansion (how do we know that it is an iteration form which is mentioned in CLHS)? Should DOLIST be re-implemented?
BTW, I find these style warnings to be quite useful. In fact, they are _right_, because there is no code which actually _reads_ from V.