From: Frank Buss
Subject: how to declare ignore for loop?
Date: 
Message-ID: <ehf5icl6ntje$.1659gfniilvh6.dlg@40tude.net>
When I write this:

    (loop for (a b) in '((1 2) (3 4)) do
          (format t "~a" b))

I'll get a warning:

Warning ...: A is bound but not referenced

When I write this:

    (loop for (a b) in '((1 2) (3 4)) do
          (declare (ignore a))
          (format t "~a" b))

I'll get another warning:

Warning ...: Badly placed declare: (DECLARE (IGNORE A))

How do I have to write it to get no warning?

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de

From: Christophe Rhodes
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <sq8xntnvqe.fsf@cam.ac.uk>
Frank Buss <··@frank-buss.de> writes:

>     (loop for (a b) in '((1 2) (3 4)) do
>           (format t "~a" b))
>
> I'll get a warning:
>   Warning ...: A is bound but not referenced
>
>     (loop for (a b) in '((1 2) (3 4)) do
>           (declare (ignore a))
>           (format t "~a" b))
>
> I'll get another warning:
>   Warning ...: Badly placed declare: (DECLARE (IGNORE A))
>
> How do I have to write it to get no warning?

(loop for (nil b) in '((1 2) (3 4)) do (format t "~A" b))

Christophe
From: Pascal Bourguignon
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <87slm1qow0.fsf@thalassa.informatimago.com>
Frank Buss <··@frank-buss.de> writes:

> When I write this:
>
>     (loop for (a b) in '((1 2) (3 4)) do
>           (format t "~a" b))
>
> I'll get a warning:
>
> Warning ...: A is bound but not referenced
>
> When I write this:
>
>     (loop for (a b) in '((1 2) (3 4)) do
>           (declare (ignore a))
>           (format t "~a" b))
>
> I'll get another warning:
>
> Warning ...: Badly placed declare: (DECLARE (IGNORE A))
>
> How do I have to write it to get no warning?

     (loop for (nil b) in '((1 2) (3 4)) 
           do  (format t "~a" b))

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NEW GRAND UNIFIED THEORY DISCLAIMER: The manufacturer may
technically be entitled to claim that this product is
ten-dimensional. However, the consumer is reminded that this
confers no legal rights above and beyond those applicable to
three-dimensional objects, since the seven new dimensions are
"rolled up" into such a small "area" that they cannot be
detected.
From: Frank Buss
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <1swm1cs3i5d3d.z7wwjss4g0sv$.dlg@40tude.net>
Pascal Bourguignon wrote:

>      (loop for (nil b) in '((1 2) (3 4)) 
>            do  (format t "~a" b))

Thanks, this works. Do you have a link to the CLHS which says that this is
allowed by the spec?

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Pascal Bourguignon
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <877j3crhha.fsf@thalassa.informatimago.com>
Frank Buss <··@frank-buss.de> writes:

> Pascal Bourguignon wrote:
>
>>      (loop for (nil b) in '((1 2) (3 4)) 
>>            do  (format t "~a" b))
>
> Thanks, this works. Do you have a link to the CLHS which says that this is
> allowed by the spec?

There have been a recent discussion about it here.
http://www.lispworks.com/documentation/HyperSpec/Body/m_destru.htm
http://www.lispworks.com/documentation/HyperSpec/Body/03_de.htm

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

PUBLIC NOTICE AS REQUIRED BY LAW: Any use of this product, in any
manner whatsoever, will increase the amount of disorder in the
universe. Although no liability is implied herein, the consumer is
warned that this process will ultimately lead to the heat death of
the universe.
From: Frank Buss
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <1hwurcl6ibyqu.102omj133iyyo$.dlg@40tude.net>
Pascal Bourguignon wrote:

> There have been a recent discussion about it here.
> http://www.lispworks.com/documentation/HyperSpec/Body/m_destru.htm
> http://www.lispworks.com/documentation/HyperSpec/Body/03_de.htm

For destructuring-bind it doesn't work with "nil":

(destructuring-bind (nil foo) '(1 2) foo)
Error: 1 does not match NIL.

but Arthur's link shows that it is legal for "loop" at least.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Rob Warnock
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <FYednW5hAPEx6QrZnZ2dnUVZ_tydnZ2d@speakeasy.net>
Frank Buss  <··@frank-buss.de> wrote:
+---------------
| For destructuring-bind it doesn't work with "nil":
| 
| (destructuring-bind (nil foo) '(1 2) foo)
| Error: 1 does not match NIL.
+---------------

But in the DESTRUCTURING-BIND case, you always *can*
use (DECLARE (IGNORE ...)).


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Frank Buss
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <l2p78gpvebt6.gh0b1eucbicc.dlg@40tude.net>
Rob Warnock wrote:

> But in the DESTRUCTURING-BIND case, you always *can*
> use (DECLARE (IGNORE ...)).

That's true. I like consistent language features like "for loop you have to
do this and for destructuring-bind you have to do that to achieve the same
result" :-)

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Pascal Bourguignon
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <87r71kpztm.fsf@thalassa.informatimago.com>
Frank Buss <··@frank-buss.de> writes:

> Pascal Bourguignon wrote:
>
>> There have been a recent discussion about it here.
>> http://www.lispworks.com/documentation/HyperSpec/Body/m_destru.htm
>> http://www.lispworks.com/documentation/HyperSpec/Body/03_de.htm
>
> For destructuring-bind it doesn't work with "nil":
>
> (destructuring-bind (nil foo) '(1 2) foo)
> Error: 1 does not match NIL.
>
> but Arthur's link shows that it is legal for "loop" at least.

Indeed, the  conclusion of the destructuring-bind thread  was that NIL
could match only NIL.


On the other hand, for LOOP, NIL is explicitely allowed as a wildcard:

http://www.lispworks.com/documentation/HyperSpec/Body/06_aag.htm
"If nil is used in a destructuring list, no variable is provided for its place."


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"Logiciels libres : nourris au code source sans farine animale."
From: Jock Cooper
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <m3ejxj21tr.fsf@jcooper02.sagepub.com>
Pascal Bourguignon <···@informatimago.com> writes:

> Frank Buss <··@frank-buss.de> writes:
> 
> > Pascal Bourguignon wrote:
> >
> >> There have been a recent discussion about it here.
> >> http://www.lispworks.com/documentation/HyperSpec/Body/m_destru.htm
> >> http://www.lispworks.com/documentation/HyperSpec/Body/03_de.htm
> >
> > For destructuring-bind it doesn't work with "nil":
> >
> > (destructuring-bind (nil foo) '(1 2) foo)
> > Error: 1 does not match NIL.
> >
> > but Arthur's link shows that it is legal for "loop" at least.
> 
> Indeed, the  conclusion of the destructuring-bind thread  was that NIL
> could match only NIL.
> 
Something like this will do the same for destructuring-bind.  The problem
with this form is it does not allow a declare block, but a little more
code would fix that.

(defmacro bind-ignoring (tree expr &body body)
  (let ((ignores nil))
    (labels ((walk-tree (tree)
	       (if (null tree) nil
		   (let ((lhs (car tree)))
		     (cons (cond ((null lhs)
				  (let ((new-sym (gensym)))
				    (push new-sym ignores)
				    new-sym))
				 ((consp lhs)
				  (walk-tree lhs))
				 (t lhs))
			   (walk-tree (cdr tree)))))))
      (let ((new-tree (walk-tree tree)))
	`(destructuring-bind ,new-tree ,expr
	  (declare (ignore ,@ignores))
	  ,@body)))))
From: Arthur Lemmens
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <op.tbevbeb0wpmq96@news.xs4all.nl>
Frank Buss wrote:

> Pascal Bourguignon wrote:
>
>>      (loop for (nil b) in '((1 2) (3 4))
>>            do  (format t "~a" b))
>
> Thanks, this works. Do you have a link to the CLHS which says that this is
> allowed by the spec?

Section 6.1.1.7 ("Destructuring"), which you can find at
http://www.lispworks.com/documentation/HyperSpec/Body/06_aag.htm

Here's the relevant part:

   If nil is used in a destructuring list, no variable is provided for its place.

    (loop for (a nil b) = '(1 2 3)
          do (return (list a b)))
   =>  (1 3)

Arthur
From: Kent M Pitman
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <ud5cvhpug.fsf@nhplace.com>
Frank Buss <··@frank-buss.de> writes:

> When I write this:
> 
>     (loop for (a b) in '((1 2) (3 4)) do
>           (format t "~a" b))
> 
> I'll get a warning:
> 
> Warning ...: A is bound but not referenced
> 
> When I write this:
> 
>     (loop for (a b) in '((1 2) (3 4)) do
>           (declare (ignore a))
>           (format t "~a" b))
> 
> I'll get another warning:
> 
> Warning ...: Badly placed declare: (DECLARE (IGNORE A))
> 
> How do I have to write it to get no warning?

Yes, you can use (loop for (nil b) ...) but it will not document what
the unused variable was, nor may it make you feel comfortable that
the pattern matching of NIL against a complex structure is going to
succeed.  This syntax (NIL for unused) is a legacy syntax that personally
I don't like and that I try not to use.

So what do I do instead? I use a legacy _idiom_ instead.

Since long before there was (DECLARE (IGNORE ...)), back to the days
when dinosaurs [ok, pdp10's] populated the earth, there was 

 (PROGN A    ; ignored
        NIL) ; to protect against there being no subsequent form

The reason this works is not that it's magic syntax understood by the
compiler, it's taht it follows directly from the language semantics.
A _is_ used, and therefore A can't be complained about.  But it's 
optimized out by nearly all compilers, so it has the net effect of an
ignore.

You can even write your own:

 (defmacro unused (&rest vars)
   `(progn ,@vars nil))

 (loop ... do (unused a b c) ...)
From: Christopher C. Stacy
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <yzlac7zzv7i.fsf@OSX663.local>
Kent M Pitman <······@nhplace.com> writes:
> Since long before there was (DECLARE (IGNORE ...)), back to the days
> when dinosaurs [ok, pdp10's] populated the earth, there was 
>
>  (PROGN A    ; ignored
>         NIL) ; to protect against there being no subsequent form
>
> The reason this works is not that it's magic syntax understood by the
> compiler, it's taht it follows directly from the language semantics.
> A _is_ used, and therefore A can't be complained about.  But it's 
> optimized out by nearly all compilers, so it has the net effect of an
> ignore.
>
> You can even write your own:
>
>  (defmacro unused (&rest vars)
>    `(progn ,@vars nil))
>
>  (loop ... do (unused a b c) ...)

ZetaLisp called this form IGNORE; this is from before there
was an IGNORE declaration.    I am not sure why it was removed
from the language in Common Lisp.   I'd rather have everyone
use the same name, rather than UNUSED, IGNORE, IGNORED, etc...
From: Pascal Costanza
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <4gajtvF1mff6jU1@individual.net>
Christopher C. Stacy wrote:
> Kent M Pitman <······@nhplace.com> writes:
>> Since long before there was (DECLARE (IGNORE ...)), back to the days
>> when dinosaurs [ok, pdp10's] populated the earth, there was 
>>
>>  (PROGN A    ; ignored
>>         NIL) ; to protect against there being no subsequent form
>>
>> The reason this works is not that it's magic syntax understood by the
>> compiler, it's taht it follows directly from the language semantics.
>> A _is_ used, and therefore A can't be complained about.  But it's 
>> optimized out by nearly all compilers, so it has the net effect of an
>> ignore.
>>
>> You can even write your own:
>>
>>  (defmacro unused (&rest vars)
>>    `(progn ,@vars nil))
>>
>>  (loop ... do (unused a b c) ...)
> 
> ZetaLisp called this form IGNORE; this is from before there
> was an IGNORE declaration.    I am not sure why it was removed
> from the language in Common Lisp.   I'd rather have everyone
> use the same name, rather than UNUSED, IGNORE, IGNORED, etc...

Maybe because there is a danger that your code is lying?

(defun add (a b)
   (unused a b)
   (+ a b))


Pascal

-- 
3rd European Lisp Workshop
July 3 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/
From: Christopher C. Stacy
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <yzlveqnyf7u.fsf@OSX663.local>
Pascal Costanza <··@p-cos.net> writes:

> Christopher C. Stacy wrote:
>> Kent M Pitman <······@nhplace.com> writes:
>>> Since long before there was (DECLARE (IGNORE ...)), back to the days
>>> when dinosaurs [ok, pdp10's] populated the earth, there was 
>>>
>>>  (PROGN A    ; ignored
>>>         NIL) ; to protect against there being no subsequent form
>>>
>>> The reason this works is not that it's magic syntax understood by the
>>> compiler, it's taht it follows directly from the language semantics.
>>> A _is_ used, and therefore A can't be complained about.  But it's
>>> optimized out by nearly all compilers, so it has the net effect of
>>> an
>>> ignore.
>>>
>>> You can even write your own:
>>>
>>>  (defmacro unused (&rest vars)
>>>    `(progn ,@vars nil))
>>>
>>>  (loop ... do (unused a b c) ...)
>> ZetaLisp called this form IGNORE; this is from before there
>> was an IGNORE declaration.    I am not sure why it was removed
>> from the language in Common Lisp.   I'd rather have everyone
>> use the same name, rather than UNUSED, IGNORE, IGNORED, etc...
>
> Maybe because there is a danger that your code is lying?
>
> (defun add (a b)
>   (unused a b)
>   (+ a b))

How is that situation improved by a multitiude of
user-defined forms that also lie?
From: Pascal Costanza
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <4galvcF1mae4qU2@individual.net>
Christopher C. Stacy wrote:
> Pascal Costanza <··@p-cos.net> writes:
> 
>> Christopher C. Stacy wrote:
>>> Kent M Pitman <······@nhplace.com> writes:
>>>> Since long before there was (DECLARE (IGNORE ...)), back to the days
>>>> when dinosaurs [ok, pdp10's] populated the earth, there was 
>>>>
>>>>  (PROGN A    ; ignored
>>>>         NIL) ; to protect against there being no subsequent form
>>>>
>>>> The reason this works is not that it's magic syntax understood by the
>>>> compiler, it's taht it follows directly from the language semantics.
>>>> A _is_ used, and therefore A can't be complained about.  But it's
>>>> optimized out by nearly all compilers, so it has the net effect of
>>>> an
>>>> ignore.
>>>>
>>>> You can even write your own:
>>>>
>>>>  (defmacro unused (&rest vars)
>>>>    `(progn ,@vars nil))
>>>>
>>>>  (loop ... do (unused a b c) ...)
>>> ZetaLisp called this form IGNORE; this is from before there
>>> was an IGNORE declaration.    I am not sure why it was removed
>>> from the language in Common Lisp.   I'd rather have everyone
>>> use the same name, rather than UNUSED, IGNORE, IGNORED, etc...
>> Maybe because there is a danger that your code is lying?
>>
>> (defun add (a b)
>>   (unused a b)
>>   (+ a b))
> 
> How is that situation improved by a multitiude of
> user-defined forms that also lie?

Ah, you're right. (The name could be 'ignorable or 'ignore-if-unused, or 
some such...)


Pascal

-- 
3rd European Lisp Workshop
July 3 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/
From: Christophe Rhodes
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <sqirmnsg77.fsf@cam.ac.uk>
······@news.dtpq.com (Christopher C. Stacy) writes:

> Pascal Costanza <··@p-cos.net> writes:
>
>> Christopher C. Stacy wrote:
>>> ZetaLisp called this form IGNORE; this is from before there
>>> was an IGNORE declaration.    I am not sure why it was removed
>>> from the language in Common Lisp.   I'd rather have everyone
>>> use the same name, rather than UNUSED, IGNORE, IGNORED, etc...
>>
>> Maybe because there is a danger that your code is lying?
>>
>> (defun add (a b)
>>   (unused a b)
>>   (+ a b))
>
> How is that situation improved by a multitiude of
> user-defined forms that also lie?

It's not; instead, it's improved by a single language-specified way of
telling the truth, which implementations are empowered to verify.

Christophe
From: Christopher C. Stacy
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <yzlac7z31th.fsf@OSX663.local>
Christophe Rhodes <·····@cam.ac.uk> writes:

> ······@news.dtpq.com (Christopher C. Stacy) writes:
>
>> Pascal Costanza <··@p-cos.net> writes:
>>
>>> Christopher C. Stacy wrote:
>>>> ZetaLisp called this form IGNORE; this is from before there
>>>> was an IGNORE declaration.    I am not sure why it was removed
>>>> from the language in Common Lisp.   I'd rather have everyone
>>>> use the same name, rather than UNUSED, IGNORE, IGNORED, etc...
>>>
>>> Maybe because there is a danger that your code is lying?
>>>
>>> (defun add (a b)
>>>   (unused a b)
>>>   (+ a b))
>>
>> How is that situation improved by a multitiude of
>> user-defined forms that also lie?
>
> It's not; instead, it's improved by a single language-specified way of
> telling the truth, which implementations are empowered to verify.

My point is that there are places in Common Lisp where you can't
put IGNORE declarations, but where you wish you could.  In the
language from which Common Lisp derived, there was a way to do that.
(For example, in the LOOP example under discussion here, where the
proposal was for the user to roll his own version of the IGNORE form,
which will not be uniformly named, and which the compiler won't be
checking for you.)  This represents a defficiency in Common Lisp, 
and I was wondering if anyone rememberd why it happened.

(I asked this 20+ years ago, too, but I don't remember the answer.
The responses so far, offline and here, suggest that maybe there isn't
a good answer, or that everyone else forgot, too.)
From: Kent M Pitman
Subject: Re: how to declare ignore for loop?
Date: 
Message-ID: <upsgqagi8.fsf@nhplace.com>
Pascal Costanza <··@p-cos.net> writes:

> Christopher C. Stacy wrote:
> > Kent M Pitman <······@nhplace.com> writes:
> ...
> >> You can even write your own:
> >>
> >>  (defmacro unused (&rest vars)
> >>    `(progn ,@vars nil))
> >>
> >>  (loop ... do (unused a b c) ...)
> > ZetaLisp called this form IGNORE; this is from before there
> > was an IGNORE declaration.    I am not sure why it was removed
> > from the language in Common Lisp.   I'd rather have everyone
> > use the same name, rather than UNUSED, IGNORE, IGNORED, etc...
> 
> Maybe because there is a danger that your code is lying?
> 
> (defun add (a b)
>    (unused a b)
>    (+ a b))

This problem is trivially solved by changing my proposal in two
ways--making it an inlined function, and renaming it to "used" (rather
than "unused").

(proclaim '(inline used))
(defun used (&rest args) args)

(defun add (a b)
  (used a b)
  (+ a b))

Now it's not lying any more. :)

I think the IGNORE function was discussed.  Note that strictly
speaking, it wasn't "removed" since there was no a priori assumption
that anything not "removed" from Zetalisp was "in" CL.  ANSI CL
started from CLTL.  CLTL was drawn from various dialects, but I don't
think it arose originally by cutting away the elements of other
languages; rather, by rescuing those elements that people couldn't do
without.

I know there was pressure for an argument named IGNORE.  (Didn't
Zetalisp ignore any argument that had the word ignore in it?  My LispM
isn't powered up right now, so I can't check.  Or maybe it was Maclisp
that did?)  Part of the issue in that case was that you needed to be
able to repeat it in the same binding list without getting a
"duplicated variable" error message, so a single variable wasn't good
enough.  You needed (defun foo (ignore-x ignore-y) ...).

- - - - 

Btw, when I translated commercial Macsyma to Common Lisp at Symbolics
(an effort not related to the translation of DOE Macsyma
[a.k.a. Maxima] to Common Lisp, which was done by Bill Schelter), I
recall using another odd kludge for a while:

(proclaim '(special ignore))

It may not be initially obvious why this should work, and in modern CL 
it's not theoretically allowed because of 11.1.2.1.2 
 [ http://www.lispworks.com/documentation/HyperSpec/Body/11_abab.htm ]
so some implementations might detect and signal an error when it's done,
but it was really handy because it meant the many cases of Macsyma doing
 (lambda (... ignore ...) ...)
or
 (defun foo (... ignore ...) ...)
would compile without warning AND it had the cool effect that if I got in
the debugger in such a function, I could peek at the variable IGNORE,
which the compiler would have dutifully made available in the dynamic
environment without affecting the running code (other than, I suppose,
in terms of speed and stack).