From: Dobes Vandermeer
Subject: Calling a function with your &rest
Date: 
Message-ID: <3636DF2F.48C0DB25@mindless.com>
I am trying to write a recursive function that passes its own &rest to
itself (minus the first entry).  The code I am using looks a lot like:

(defun the-func (foo &rest the-rest)
	(...)
	(eval (list* 'the-func (cdr the-rest)))
	)

Unfortunately, it is giving me errors.  If you have written this kind of
function before, please tell me what I am doing wrong.

Thanks!

From: Rainer Joswig
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <joswig-2810981100220001@pbg3.lavielle.com>
In article <·················@mindless.com>, Dobes Vandermeer
<·····@mindless.com> wrote:

> I am trying to write a recursive function that passes its own &rest to
> itself (minus the first entry).  The code I am using looks a lot like:
> 
> (defun the-func (foo &rest the-rest)
>         (...)
>         (eval (list* 'the-func (cdr the-rest)))
>         )
> 
> Unfortunately, it is giving me errors.  If you have written this kind of
> function before, please tell me what I am doing wrong.
> 
> Thanks!




(defun the-func (foo &rest the-rest)
  (declare (ignore foo))
  (when the-rest
    (print the-rest)
    (apply #'the-func foo (rest the-rest))))

? (the-func 1 2 3 4 5 6 7)
(2 3 4 5 6 7) 
(3 4 5 6 7) 
(4 5 6 7) 
(5 6 7) 
(6 7) 
(7) 
NIL

-- 
http://www.lavielle.com/~joswig
From: Dobes Vandermeer
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <3636F09C.84A51ED9@mindless.com>
Rainer Joswig wrote:
> 
> In article <·················@mindless.com>, Dobes Vandermeer
> <·····@mindless.com> wrote:
> (defun the-func (foo &rest the-rest)
>   (declare (ignore foo))
>   (when the-rest
>     (print the-rest)
>     (apply #'the-func foo (rest the-rest))))

Aha.. apply is the key.  Thanks!

There is something else I am trying to figure out.

What makes the result of a function "setf'able"?

How can I make my access functions work this way?

Help appreciated.
From: Barry Margolin
Subject: SETFable forms Re: Calling a function with your &rest
Date: 
Message-ID: <3jJZ1.98$yc2.1335983@burlma1-snr1.gtei.net>
In article <·················@mindless.com>,
Dobes Vandermeer  <·····@mindless.com> wrote:
>There is something else I am trying to figure out.
>
>What makes the result of a function "setf'able"?

There has to be a SETF function or expander that tells SETF how to
implement the assignment.

>How can I make my access functions work this way?

You can define a function named (setf <your function>) or use DEFSETF or
DEFINE-SETF-EXPANDER to define a SETF expander.  See section 7.2
Generalized Variables of CLtL2 (note: at the time the book was written,
DEFINE-SETF-EXPANDER was called DEFINE-SETF-METHOD, and may still have that
name in some implementations).

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
From: Jens Kilian
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <sfn26gnc6g.fsf@bstde026.bbn.hp.com>
Dobes Vandermeer <·····@mindless.com> writes:
> I am trying to write a recursive function that passes its own &rest to
> itself (minus the first entry).  The code I am using looks a lot like:
> 
> (defun the-func (foo &rest the-rest)
> 	(...)
> 	(eval (list* 'the-func (cdr the-rest)))
> 	)
> 
> Unfortunately, it is giving me errors.  If you have written this kind of
> function before, please tell me what I am doing wrong.

Do not use EVAL, it's evil.

You *could* use APPLY, like this

    (defun the-func (foo &rest the-rest)
	(...)
	(apply #'the-func (cdr the-rest))
	)

But this will probably be inefficient because it creates copies of the
&rest list.  Use DO, DOLIST, LOOP, MAPCAR or some other iterating
construct instead.

HTH,

	Jens.
-- 
··········@acm.org                 phone:+49-7031-14-7698 (HP TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-14-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]
From: Kent M Pitman
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <sfw90i0en6s.fsf@world.std.com>
[My reply appears to be directed at Jens here, but it's not really
 personal to him. See remarks at end about that.]

Jens Kilian <···········@bbn.hp.com> writes:

> Dobes Vandermeer <·····@mindless.com> writes:
> > I am trying to write a recursive function that passes its own &rest to
> > itself (minus the first entry).  The code I am using looks a lot like:
> > 
> > (defun the-func (foo &rest the-rest)
> > 	(...)
> > 	(eval (list* 'the-func (cdr the-rest)))
> > 	)
> > 
> > Unfortunately, it is giving me errors.  If you have written this kind of
> > function before, please tell me what I am doing wrong.
>
> Do not use EVAL, it's evil.
 
Do not use the word evil.  It's evil.  (Well, no rule is perfect.)

Look, it doesn't help to have style rules based on mythology.  
EVAL has appropriate uses, this is just not one of them.

To know when the appropriate time to use something is, one must
actually understand the correct times to use it and the correct times
not to.  Just believing it is never to be used is likely to get you
into trouble, too, since working without EVAL will leave you crippled
in other (admittedly obscure, but still important) cases.

I usually say that the presence of EVAL is a "red flag" meaning that
you need to notice it and observe the situation carefully and investigate
the alternatives before proceeding.

EVAL may be needed when you are receiving a whole new form into Lisp
that you have not seen before; for example, you are writing a
full-powered scripting language.  You can write your own EVAL to get
around this, but its quite painful in many cases.  (In other cases,
where you may not need the full power of Lisp or for security
reasons may not want to ALLOW it, writing your own EVAL can be better.)

A downside of using EVAL is that it means if you later try to build a
production system for delivery, you have to include the entire
interpreter, which can add considerable size to the image.  However,
for some uses this is not an issue.  ON THE OTHER HAND, if your choice
is between including the evaluator or the compiler, you may sometimes
find the evaluator is smaller and that it's better to use EVAL than
COMPILE for some applications.

Another downside of using EVAL is that it is, for some applications,
slow.  HOWEVER, it's worth noting that "slow" is not a simple 
one-dimensional quality.  For example, if you have a large expression
and you plan to execute only a tiny part of it, interpreted execution
may be faster than the cost of compiling the whole expression and 
then executing the compiled part.  (If you don't know why this is
so, you need to ask someone else other than me who has more time to
explain it to you.)

EVAL *might* be more space conservative than COMPILE because it
doesn't have to create an intermediate an intermediate object only to
throw it away.  (Details of space use are, of course, implementation
independent.  In some implementations, EVAL secretly DOES compile
already, and so what I said may not be true.)

I'm not sure this is an exhaustive list--I only meant here to show
that the space of issues you have to deal with in order to answer the
question is tricky.

It *is* true that inappropriate use of EVAL is often correlated with
a newbie's misunderstanding of the language and how to use it.  EVAL
is a new thing they don't understand, and it is often used where it
shouldn't be or used wrong when it is called for.  In short, not
every user of EVAL knows what s/he's doing.  The fix for this,
however, is not to teach the person the new factoid "You are too 
stupid to use EVAL and so must never do that."  For a person to learn
the "lemma" that they are stupid has ill effects--or, if it's really
true, you might want to tell them they shouldn't be programming.
But you're pushing a very fragile ethical line when you start to make
decisions like this for other people.  Further, for a person
to learn the "lemma" that there are right and wrong answers to how
to code independent of the context of the coding has ill effects,
and it puts into question the judgment of the recommender.

Incidentally, the reason EVAL is wrong above is not something you'll
find in the Bible or any other book of good and evil.  The reason EVAL
is wrong is that (eval (list* 'the-func (cdr the-rest))), where 
the-rest is a list of actual arguments, RE-evaluates the actual 
arguments bound to x, which were presumably already evaluated.
If the-func is working with numbers, they may not mind and it might
work for some examples, but not others.  But consider:
 (defun the-func (&rest args)
   (cond ((null args) ;<-- Riesbeck take note, I used NULL
          '())
         (t (list* 'foo (car args)
		   (eval (cons 'the-func (cdr args)))))))
This means if you do 
 (the-func 1 2)
you should get (foo 1 foo 2) and if you do
 (the-func 'x)
you should get (foo x) but if you do
 (the-func 'x 'y)
you should get an error saying that y is unbound because
on the recursive call you will do
 (list* 'foo 
        (car args) ;yields X
        (eval             ;evals (THE-FUNC Y)
         (cons 'the-func   
               (cdr args) ;yields (Y)
         )))
So the correct rewrite using EVAL is
 (defun the-func (&rest args)
   (cond ((null args) '())
         (t (list* 'foo (car args)
                   (eval (cons 'the-func
			       (mapcar #'(lambda (x) `',x)
				       args)))))))

And now that you understand how to code it correctly using EVAL,
you can finally proceed to understanding correctly why EVAL is
wrong IN THIS CASE--because (a) a lot of unneeded consing is
done and (b) the use of eval causes you to have to add a bunch
of quoting back to something just so the eval can strip the
quoting, defeating the purpose of EVAL, which is to evaluate
something.  At this point, APPLY is clearly the winner because
since no evaluation is going on anyway--only function 
application--then the operator that does function application
*is* the right thing to use merely on the basis of simplicity,
and having nothing to do with "evil".

> You *could* use APPLY, like this
> 
>     (defun the-func (foo &rest the-rest)
> 	(...)
> 	(apply #'the-func (cdr the-rest))
> 	)
> 
> But this will probably be inefficient because it creates copies of the
> &rest list. 

Actually, it may or may not create copies of it.  The compiler in a
given implementation may be able to do the data flow analysis necessary
to unroll this.  Probably you meant to say

 "But this will probably be inefficient because it probably creates
 copies of the &rest list"

;-)

> Use DO, DOLIST, LOOP, MAPCAR or some other iterating
> construct instead.

I do agree that in the case that you want the compiler to infer an 
iteration, using an iteration construct to communicate that information
is the best way to do that.


> 
> HTH,
 
Me, too.

> 	Jens.

Btw, Jens, I hope you don't mind my having taken this opportunity to
pick on your example.  Not knowing you personally, I'm not suggesting
you don't necessarily to know any of the things I said above here.
It's just that I hear things like what you said a lot, and I wanted to
take the opportunity to speak generally to the whole class of
"mysticism" that sometimes seems to surround style rules.  And this was
as good a chance as any.  So, at least for me, your post did "help". :-)

DISCLAIMER: NONE of the examples of code i've included are tested
 in a running implementation.   I *hope* they work (by which in some
 cases I mean, I hope they generate the error messages I'm assuming
 they do), but didn't have time to check for sure.  Someone please 
 post a correction if they notice I've screwed something up so Dobes
 and others don't get further confused...  (I like that this newsgroup
 works as a team effort in that regard.  Much better than many.)
 --Kent
From: Marco Antoniotti
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <lwogqwr97t.fsf@galvani.parades.rm.cnr.it>
Kent M Pitman <······@world.std.com> writes:

> EVAL *might* be more space conservative than COMPILE because it
> doesn't have to create an intermediate an intermediate object only to
> throw it away.  (Details of space use are, of course, implementation
> independent.  In some implementations, EVAL secretly DOES compile
> already, and so what I said may not be true.)
> 

EVAL: the ultimate JIT compiler.

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 16, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Kent M Pitman
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <sfwhfwowrpd.fsf@world.std.com>
Marco Antoniotti <·······@galvani.parades.rm.cnr.it> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> > EVAL *might* be more space conservative than COMPILE because it
> > doesn't have to create an intermediate an intermediate object only to
> > throw it away.  (Details of space use are, of course, implementation
> > independent.  In some implementations, EVAL secretly DOES compile
> > already, and so what I said may not be true.)
> > 
> 
> EVAL: the ultimate JIT compiler.

Well, indeed.  In my day we were taught that a compiler was an
early-binding interpreter or an interpreter was a late-binding
compiler.  I suppose they've gotten away from that though it still
seems a useful way to sometimes view the issue.  And "JIT" ("Just in
Time", in case someone missed the reference) is pretty much a synonym
for "late-binding".  We just have to periodically update the buzzword
used for the same old concept to make sure that anyone not tracking
the market moment-to-moment is locked out of any useful ability to
converse.  Locking people gratuitously out of the market through use
of gratuitous new terminology is how business is done these days,
don't you know?  (sigh)  

Don't get me wrong--I'm all for new ways to view things, and "Just In
Time" is a useful conceptualization.  I just wish they'd link it up
with the old name so that there were other ways you could view the
same thing, and there was an acknowledgment that this is an old idea.
When you replace terms and ideas rather than expand on them, you don't
fundamentally improve the world.  You only improve the world when you
allow people to relate old ideas to new so they are expanding their
world model instead of continually chasing a new and disjoint one.

This relates to my beef about tail recursion in Scheme, which I think
is a fine new way of looking at an old idea that offers interesting
leverage, but that should not be thought of as a replacement for
the old idea of iterating, which has its own power in terms of being
a simpler formulation for the set of simple cases where the more
complex formulation is not needed.
From: Rob Warnock
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <719nqg$1cdpn@fido.engr.sgi.com>
Kent M Pitman  <······@world.std.com> wrote:
+---------------
| This relates to my beef about tail recursion in Scheme, which I think
| is a fine new way of looking at an old idea that offers interesting
| leverage, but that should not be thought of as a replacement for
| the old idea of iterating, which has its own power in terms of being
| a simpler formulation for the set of simple cases where the more
| complex formulation is not needed.
+---------------

[And at the risk of getting flamed for it,] I'll say again that one of
the additional dangers in talking about tail-recursion as "the Scheme
way of iterating" is that the storage & variable-binding behaviors of
Scheme "iteration" -- as it is conventionally coded [with the state held
in bound variables in a "do" or "(let loop...)" or explicit self-tail-call
parameters] -- and Common Lisp iterative constructs are not the same,
either. For example, in Scheme's "do" each trip around the loop binds
the variables to *fresh* locations, which are then initialized with
the "step" values, while in Common Lisp's "do" the *same* bindings are
*assigned* to ("as with psetq", sez the HyperSpec) with the "step" values. 

Not only can this lead to very different allocation patterns and garbage
collector behavior (as I think I mentioned before in this thread), but
also to very different results!!  Consider this somewhat contrived example
[actually run on several Schemes and on CLISP, just to be sure! ;-} ]:

    === Scheme ===                      === Common Lisp ===
    > (define (foo)                     > (defun foo ()
	(do ((i 0 (+ 1 i))                  (do ((i 0 (+ 1 i))
	     (j (lambda () 'first)               (j (lambda () 'first)
		(lambda () i))                      (lambda () i))
	     (k '() (cons j k)))                 (k '() (cons j k)))
	    ((> i 3) (reverse k))))             ((> i 3) (reverse k))))
					FOO
    > (map (lambda (x) (x)) (foo))      > (mapcar #'funcall (foo))
    (first 0 1 2)                       (FIRST 4 4 4)
    >                                   >

The "foo"s are IDENTICAL (well, define/defun syntax), yet the results
certainly aren't!


-Rob

p.s. You *can*, of course, write a "do" loop in Scheme that gives CL-like
semantics for this example, but you have to go to more trouble:

    > (define (foo2)
        (let ((shared-i 'ignored)) 
          (do ((i 0 (+ 1 i))
               (j (lambda () 'first) 
                  (lambda () shared-i)) 
               (k '() (cons j k)))  
              ((> i 3) (set! shared-i i) (reverse k))
            (set! shared-i i))))
    > (map (lambda (x) (x)) (foo2))
    (first 4 4 4)
    > 

[And, yes, I know, the second "set!" is not necessary... in *this* example...]

-----
Rob Warnock, 8L-855		····@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
2011 N. Shoreline Blvd.		FAX: 650-964-0811
Mountain View, CA  94043	PP-ASEL-IA
From: Jens Kilian
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <sfd87bmtqr.fsf@bstde026.bbn.hp.com>
Kent M Pitman <······@world.std.com> writes:
> Jens Kilian <···········@bbn.hp.com> writes:
[...]
> > Do not use EVAL, it's evil.
>  
> Do not use the word evil.  It's evil.  (Well, no rule is perfect.)
> 
> Look, it doesn't help to have style rules based on mythology.  
> EVAL has appropriate uses, this is just not one of them.

OK.  I should have explained *why* it is evil^H^H^H^Hinappropriate in that
particular example.

[Lucid explanation snipped.]

> > You *could* use APPLY, like this
> > 
> >     (defun the-func (foo &rest the-rest)
> > 	(...)
> > 	(apply #'the-func (cdr the-rest))
> > 	)
> > 
> > But this will probably be inefficient because it creates copies of the
> > &rest list. 
> 
> Actually, it may or may not create copies of it.  The compiler in a
> given implementation may be able to do the data flow analysis necessary
> to unroll this.  Probably you meant to say
> 
>  "But this will probably be inefficient because it probably creates
>  copies of the &rest list"
> 
> ;-)

Yes indeed.  Me'um not native speaker.

> Btw, Jens, I hope you don't mind my having taken this opportunity to
> pick on your example.  Not knowing you personally, I'm not suggesting
> you don't necessarily to know any of the things I said above here.

No offense taken.  It's been a few years since I last did any amount of
work in Lisp.

Bye,

	Jens.
-- 
··········@acm.org                 phone:+49-7031-14-7698 (HP TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-14-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]
From: Marc Cavazza
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <3638844E.580A2703@bradford.ac.uk>
Kent M Pitman wrote:

Actually, I found the reply from Kent trying to collect possible exceptional
uses of EVAL and providing a benefits analysis quite interesting

> > You *could* use APPLY, like this
> >
> >     (defun the-func (foo &rest the-rest)
> >       (...)
> >       (apply #'the-func (cdr the-rest))
> >       )
> >
> > But this will probably be inefficient because it creates copies of the
> > &rest list.

what would you recommend then if you end up with somethingyou cannot APPLY (e.g.
AND) -- not using EVERY of course ?

Also, I think a previous thread commented on the
(old-fashioned) use of eval for accessing internal
representations (e.g. in a frame-based system)
instead of using hash-tables or p-lists, but did not
gave examples:

I guess this would look like the following,
where your frame representation is, let's say,
a (defstruct frame <...>)

...
(let ((name (gensym "frame-")))
    (set name (make-frame <parameters>))
    (setq *table* (cons name *table*)
...

where you would access the frames from the global
*table* by EVALuating the symbol ?


Marc Cavazza
--
____________________________________________________________________
Prof. Marc Cavazza              http://www.eimc.brad.ac.uk/~mcavazza

EIMC Department                 Phone: +44 (0)1274 236 135
University of Bradford          Fax:   +44 (0)1274 383 727
Bradford, West Yorkshire        E-mail: ·········@bradford.ac.uk
BD7 1DP -- United Kingdom
____________________________________________________________________
From: Rainer Joswig
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <joswig-2910981631190001@pbg3.lavielle.com>
In article <·················@bradford.ac.uk>, Marc Cavazza
<·········@bradford.ac.uk> wrote:

> Kent M Pitman wrote:
> 
> Actually, I found the reply from Kent trying to collect possible exceptional
> uses of EVAL and providing a benefits analysis quite interesting
> 
> > > You *could* use APPLY, like this
> > >
> > >     (defun the-func (foo &rest the-rest)
> > >       (...)
> > >       (apply #'the-func (cdr the-rest))
> > >       )
> > >
> > > But this will probably be inefficient because it creates copies of the
> > > &rest list.

You also can use a declaration "DYNAMIC-EXTENT" for the
rest list if possible.

> Also, I think a previous thread commented on the
> (old-fashioned) use of eval for accessing internal
> representations (e.g. in a frame-based system)
> instead of using hash-tables or p-lists, but did not
> gave examples:
> 
> I guess this would look like the following,
> where your frame representation is, let's say,
> a (defstruct frame <...>)
> 
> ...
> (let ((name (gensym "frame-")))
>     (set name (make-frame <parameters>))
>     (setq *table* (cons name *table*)
> ...
> 
> where you would access the frames from the global
> *table* by EVALuating the symbol ?

Why do you need the *table* list?
If you want to map over all for example frames,
just use a separate package and iterate over
this package.

----

You can use the symbol table as a hashtable.
But symbols do have some overhead (space). Why not
just use a hashtable directly, if possible?

Why not just use:

(setf (gethash frame-name *frames*) frame)

If you have a weak hashtable, frames could also
be GCed when not accessible anymore (not portable).

-- 
http://www.lavielle.com/~joswig
From: Marc Cavazza
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <3638E389.E176065@bradford.ac.uk>
Rainer Joswig wrote:

> Why not
> just use a hashtable directly, if possible?
>
> Why not just use:
>
> (setf (gethash frame-name *frames*) frame)
>
> If you have a weak hashtable, frames could also
> be GCed when not accessible anymore (not portable).

Sorry I was not clear enough.

I tried to refer to an "old" programming style (as I understood
from the previous thread), _without_ using hash tables

The general solution would indeed use hash tables as you
mentioned

Marc
From: Steve Gonedes
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <m2vhl4o0am.fsf@KludgeUnix.com>
Dobes Vandermeer <·····@mindless.com> writes:

< 
< 
< I am trying to write a recursive function that passes its own &rest to
< itself (minus the first entry).  The code I am using looks a lot like:
< 
< (defun the-func (foo &rest the-rest)
< 	(...)
< 	(eval (list* 'the-func (cdr the-rest)))
< 	)
< 
< Unfortunately, it is giving me errors.  If you have written this kind of
< function before, please tell me what I am doing wrong.

Have you thought about using a local function to recurse through the
list? This may clarify your intentions.

(defun the-func (foo &rest the-rest)
  ;; establish a local function
  (labels ((the-func-aux (fn items)
            (cond ((endp items) nil)
                  (t (funcall fn items)
                     (the-func-aux fn (cdr items))))))
   ;; call the local function `the-func-aux'
   (the-func-aux foo the-rest)))

(the-func #'print 1 2 3 4 5)

=> (1 2 3 4 5) 
   (2 3 4 5) 
   (3 4 5) 
   (4 5) 
   (5) 
   NIL
From: Pierre Mai
Subject: Re: Calling a function with your &rest
Date: 
Message-ID: <87k91lx8e1.fsf@dent.isdn.cs.tu-berlin.de>
Dobes Vandermeer <·····@mindless.com> writes:

> I am trying to write a recursive function that passes its own &rest to
> itself (minus the first entry).  The code I am using looks a lot like:
> 
> (defun the-func (foo &rest the-rest)
> 	(...)
> 	(eval (list* 'the-func (cdr the-rest)))
> 	)
> 
> Unfortunately, it is giving me errors.  If you have written this kind of
> function before, please tell me what I am doing wrong.

Never, ever use eval[1]!

(defun silly-fun (sum &rest rest)
  (if (null rest)
      sum
      (apply #'silly-fun (+ sum (first rest)) (rest rest))))

Lookup apply in the Common Lisp Hyperspec for more information.

And beware:  You are not allowed to _change_ the structure of the rest 
list!  If you want to do this, you will have to copy it first via
copy-list.

Also, &rest-arguments are not particularly fast in function call
overhead.  Using explicit list arguments might be more apropriate in
your situation.

Footnotes: 
[1]  Except where it is really needed ;)  But this is very seldom...

-- 
Pierre Mai <····@acm.org>               http://home.pages.de/~trillian/
  "Such is life." -- Fiona in "Four Weddings and a Funeral" (UK/1994)