[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

&REST



Now, I'm SURE this one has come up, but here goes...

In your favorite implementation of CL, try this:

(DEFUN FOO (&REST A) A)
(FOO 1 2 3)

By direct experience, both TI (version 2) and Symbolics (Version 7) do not
return (1 2 3).  They have an efficiency hack wherein the cons space used to
create the &REST arg is reused, and thus the pointer that is returned (which
is a pointer to a list) is pointing to memory which does not contain the same
thing as when the pointer was last evaluated.  That is, he process of
returning has the side effect of changing the contents of the list created
when binding A.  Seth Goldman tells me that several Macintosh Lisps also
behave this way.

CLtL, on page 61, states:

"If there is a rest parameter, it is bound to a list of all as-yet-unprocessed
arguments."

This part works fine.  These implementations DO make a list and bind it and
all that.  The symbolics manual specifically warns one to use copylist if you
want to return any tail or sublist of an &REST argument (thus consing it in
"real" memory).

As I am putting together the test suite, I have run into a problem:  Many
tests actualy use &REST.  These seem to expect to get a proper list and not
some imaginary list that changes when the function returns.  My feelings are
that the above efficiency hack is a bug, even though it may be "supported by
hardware".  

Can anyone show me a valid justification for the above behavior?  So far, HP
has an implementation that does the correct thing (returns the list).  TI, in
their version 3 software (which we are beta-ing) has fixed this.  Note that
page 60 clearly states, about the body in a lambda,

"The body consists of any number of forms (possibly zero).  These forms are
evaluated in sequence, and the results of the last form only are returned as
the results of the application..."

This does not allow for any alteration of the results of the last form.  

OK?

RB