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

&Rest Lists



Ideally &Rest arguments should be the exclusive property of the 
function which defines them.  Two funny restrictions have sometimes
been imposed on &Rest lists to enable certain optimizations.  The
question is whether the value of the optimization exceeds the cost
of documenting and not violating the restrictions.  

The first optimization/restriction primarilly allows stack-consing at the
expense of making &Rest lists become undefined when the function returns.
This is a fairly large optimization but it has already been prohibited
(in the general case) by CLtL.

The second optimization/restriction primarilly allows constant lists to
be used as &Rest lists at the expense of prohibiting functions from
modifying their &rest lists.  However, since CLtL already requires
&Rest lists to exist after the function returns they will almost
always have to be CONSed as the function is called, unless fancy
optimizations have occured.  The primary case where this optimization
still could matter is when Apply is used with a constant list to call
a function with an &Rest list that does not have to be modified.

I think that this optimization is rather minor, except in situations
where a programmer has intentionally set up the code to take advantag
of this.  However, it is a simple matter to rework this kind of function
call to get the optimized behavior in a fully portable way.  
Instead of:
(defun bar (x)
  (apply #'foo x))

(defun foo (&rest theList)
  ...)

Use:
(defun bar (x)
  (foo x))

(defun foo (theList)
  ...)

This new code is guaranteed to be portable and efficient, and it is
also easier to read.  Admittedly this rewrite isn't good for 100%
of the cases, but it does make the optimized behavior of &Rest lists
less important.  Sufficiently so that I think &Rest lists should
be implemented so that they behave as if:

(defun foo (&rest x) ...)

Should behave as if it were defined:

(defun foo (&rest G0047)     ;Gensym really
  (let ((x (copy-list G0047)))
     ...))

I think this fully and precisely specifies the semantics of &Rest.

Chris Eliot