From: Kyle M on
On Nov 24, 3:47 pm, Tim Bradshaw <t...(a)cley.com> wrote:
> On 2009-11-24 15:00:54 +0000, Kyle M <kyle...(a)gmail.com> said:
>
> > Now that I think about it I'm wondering if this is actually an
> > implementation issue:
>
> > (loop for x in '(1 2 3)
> >      return 'nothing))
>
> > This will not warn me about not using x (in Allegro).
>
> I think it is, probably, not an implementation issue, but I am not sure.
>
> For DOTIMES (for instance) it is explicitly undefined whether each
> variable is rebound for each iteration or whether there is only one
> binding per variable.  This means it is undefined whether the variable
> is ignored or not if you do not use it.  Simplifying to the point of
> being wrong, the difference is between something like:
>
> (...
>   (let ((i ...))
>      ...your code...))
>
> And
>
> (...bind i...
>    (locally
>       ...your code...)
>    ...
>    (incf i)
>    ...)
>
> In the latter case, I is *not* ignored even if your code does not use it,
>
> For LOOP, I *think* it is clear that the expansion is more like the
> second case.  So the variables are not ignored, even if your code does
> not use them.  However I am not sure that this is required to be the
> case: I think it probably is, but I'm not completely sure.
>
> This can make huge differences for code which returns closures of course.
>
> I can imagine implementations clever enough that they realised that no
> *user* code used a binding and warned about that, even though the LOOP
> expansion itself did assign to the variable.
>
> I have used "variable" and "binding" sloppily above.

I emailed Franz about it, and Steve Haflich made an interesting point
about the spec. I hope he doesn't mind my paraphrasing him.

The section on ignore/ignorable says:

"The stream variables established by with-open-file, with-open-stream,
with-input-from-string, and with-output-to-string, and all iteration
variables are, by definition, always "used". Using (declare (ignore
v)), for such a variable v has unspecified consequences."

The term iteration-variable is in the glossary, and basically includes
the variables x, y, and z in the following loop:

(loop for x in list1
for (y z) in list2
...)

So, basically, these variables are considered "used", even if they
aren't used. So the compiler should not warn me at all.

Kyle
From: Ron Garret on
In article <2009112420473716807-tfb(a)cleycom>,
Tim Bradshaw <tfb(a)cley.com> wrote:

> On 2009-11-24 15:00:54 +0000, Kyle M <kylemcg(a)gmail.com> said:
>
> > Now that I think about it I'm wondering if this is actually an
> > implementation issue:
> >
> > (loop for x in '(1 2 3)
> > return 'nothing))
> >
> > This will not warn me about not using x (in Allegro).
>
> I think it is, probably, not an implementation issue, but I am not sure.
>
> For DOTIMES (for instance) it is explicitly undefined whether each
> variable is rebound for each iteration or whether there is only one
> binding per variable. This means it is undefined whether the variable
> is ignored or not if you do not use it. Simplifying to the point of
> being wrong, the difference is between something like:
>
> (...
> (let ((i ...))
> ...your code...))
>
> And
>
> (...bind i...
> (locally
> ...your code...)
> ...
> (incf i)
> ...)
>
> In the latter case, I is *not* ignored even if your code does not use it,
>
> For LOOP, I *think* it is clear that the expansion is more like the
> second case. So the variables are not ignored, even if your code does
> not use them. However I am not sure that this is required to be the
> case: I think it probably is, but I'm not completely sure.
>
> This can make huge differences for code which returns closures of course.
>
> I can imagine implementations clever enough that they realised that no
> *user* code used a binding and warned about that, even though the LOOP
> expansion itself did assign to the variable.
>
> I have used "variable" and "binding" sloppily above.

In CL, variables are bindings, so the two terms can be freely
interchanged. Where you were a little sloppy is using the term
"variable" where you meant "variable name", e.g. "it is explicitly
undefined whether each variable is rebound for each iteration".
Strictly speaking that should have been, "it is explicitly undefined
whether each variable NAME is rebound for each iteration."

rg
From: Kenneth Tilton on
russell_mcmanus(a)yahoo.com wrote:
> Kyle M <kylemcg(a)gmail.com> writes:
>
>> Here's a question for the loopers. Say I'm using loop destructuring
>> like this:
>>
>> (defun foo (some-list)
>> (loop for (a b c) in some-list
>> do ;; code that uses a and c, but not b:
>> (print a) (print c)))
>>
>> (compile 'foo) -> Warning: Variable b is never used.
>
> Perhaps the obvious?
>
> (defun foo (some-list)
> (loop for (a b c) in some-list
> do b
> (print a) (print c)))

Or the perhaps less obvious:

(defun frank (some-list)
(loop for (a b c) in some-list
do b do b do
(print a) (print c)))

?

kt

--

http://thelaughingstockatpngs.com/
http://www.facebook.com/pages/The-Laughingstock/115923141782?ref=nf
From: Tobias C. Rittweiler on
Tim Bradshaw <tfb(a)cley.com> writes:

> On 2009-11-24 15:00:54 +0000, Kyle M <kylemcg(a)gmail.com> said:
>
>> Now that I think about it I'm wondering if this is actually an
>> implementation issue:
>>
>> (loop for x in '(1 2 3)
>> return 'nothing))
>>
>> This will not warn me about not using x (in Allegro).
>
> I think it is, probably, not an implementation issue, but I am not sure.
>
> For DOTIMES (for instance) it is explicitly undefined whether each
> variable is rebound for each iteration or whether there is only one
> binding per variable. This means it is undefined whether the variable
> is ignored or not if you do not use it.

Nope, CLHS dictionary entry for IGNORE:

The stream variables established by with-open-file, with-open-stream,
with-input-from-string, and with-output-to-string, and all iteration
variables are, by definition, always ``used''. Using (declare (ignore
v)), for such a variable v has unspecified consequences.

For understandable reasons, I don't think any implementation actually
completely adheres to that.

-T.
From: Tim Bradshaw on
On 2009-11-25 07:42:30 +0000, "Tobias C. Rittweiler"
<tcr(a)freebits.de.invalid> said:

> Nope, CLHS dictionary entry for IGNORE:
>
> The stream variables established by with-open-file, with-open-stream,
> with-input-from-string, and with-output-to-string, and all iteration
> variables are, by definition, always ``used''. Using (declare (ignore
> v)), for such a variable v has unspecified consequences.
>
> For understandable reasons, I don't think any implementation actually
> completely adheres to that.

OK, that's interesting (and answers the question). It's hard to see
how this would work for an implementation which did rebind each time
("It is implementation-dependent whether dolist establishes a new
binding of var on each iteration or whether it establishes a binding
for var once at the beginning and then assigns it on any subsequent
iterations."): such an implementation would have to somehow secretly
"touch" the binding (or have a secret declaration that the variable was
actually used, even though it might not be).