[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
&REST Lists
I don't think requiring &rest lists to be (conceptually) freshly consed is
somehow "automatically unsharing" structure. It depends on how you see the
semantics of function calling - I think a function gets a certain number of
individual arguments, and &REST requests that some of those arguments be
constructed into a list. It's all internal to the function and nobody else's
business. APPLY's contract is to pass *elements* of a list to a function as
arguments. From this point of view, having a list given to APPLY suddenly
show up inside some function, without being passed as an argument to that
function, is not a natural case of sharing -- it's a case of unexpected
collapsing of equal structures, not that much different from, say,
(eq (union (list 'a) (list 'b)) (union (list 'a) (list 'b))) ==> T.
On the practical side, there is an idiom that occurs in almost every
non-trivial portable common lisp program I've seen, which looks something like
this:
(DEFUN FN (&REST FOO)
#+<systems known to not cons &rest args> (SETQ FOO (COPY-LIST FOO))
...)
or sometimes just like this:
(DEFUN FN (&REST FOO) (SETQ FOO (COPY-LIST FOO)) ...)
For example, a quick scan through PCL (it happened to be handy) finds at least
5 instances of this idiom, 2 with the conditionalization and 3 without. The
COPY-LIST is of course wasteful in implementations which guarantee no
user-visible sharing of &rest lists, but it is also wasteful in the
APPLY/&REST-optimizing implementations when the function is being called
normally (i.e. with no handy pre-consed arg list to reuse), which is usually
most of the time. If Common Lisp doesn't require unshared &rest lists, then I
think it must provide a declarative version of this idiom so the COPY-LIST can
be portably avoided when it's redundant. Seems to me that the fact that this
is a common case where users find a need for conditionalization indicates a
real deficiency in Common Lisp's specification.
Regarding the case of a format-like function applying a format-like function
and so on, wouldn't it be cleaner and even more efficient to provide some
special construct for that case, such as (off the top of my head) a RE-APPLY,
which would request the caller's args to be passed on to the callee? (And
wasn't somebody working on designing an &MORE or some such abstraction which
avoided consing altogether? Whatever happened to that?)