Kent M Pitman <pitman@nhplace.com> wrote:
+---------------
| Marco Antoniotti <marcoxa@gmail.com> writes:
| > > Somehow you can do it yourself, given that you know what are the keys
| > > you do not want (i.e., those you declared)
| > > (defun test1 (&rest keys &key x y z &allow-other-keys)
| > > (remf keys :x)
| > > (remf keys :y)
| > > (remf keys :z)
| > > (values x y z keys))
...
| > Of course, this is "removing them in the function body", but it isn't
| > all that painful.
|
| I've only got a second this morning so maybe someone can research this
| for me to see if we fixed this, but one of the obscure thinks about
| this is that under CLTL this was ill-defined in terms of side-effect
| behavior, and I don't remember if we fixed it for ANSI CL. The issue is
| that REMF sometimes does an assignment but sometimes does rplacd-like
| operations, and implementations are permitted in some cases not to copy
| the &rest list, when APPLY is used.
...
| There could be implementations that want to share the tail in
| doing the APPLY and that consequently leave you open to accidental
| modification.
|
| Or maybe it was only when there was a DYNAMIC-EXTENT declaration.
+---------------
Permitted (but not required) in *all* cases [not tied to DYNAMIC-EXTENT],
as far as I can determine:
http://alu.org/HyperSpec/Body/sec_3-4-1-3.html
3.4.1.3 A specifier for a rest parameter
...
The value of a rest parameter is permitted, but not required,
to share structure with the last argument to APPLY.
and:
http://alu.org/HyperSpec/Body/fun_apply.html
Function APPLY
...
When the function receives its arguments via &REST, it is
permissible (but not required) for the implementation to bind
the rest parameter to an object that shares structure with the
last argument to APPLY. Because a function can neither detect
whether it was called via APPLY nor whether (if so) the last
argument to APPLY was a constant, conforming programs must
neither rely on the list structure of a rest list to be freshly
consed, nor modify that list structure.
+---------------
| Another "conservative" thing is never to side-effect an &rest list,
| I suppose, but then, if you even just return one of these lists, as in
| (defun test1 (&rest args) args)
| and then later do the side-effect, you're perhaps still at risk.
+---------------
Yup, at least in a "conforming program". ;-}
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607