Subject: Re: lambda list question
From: rpw3@rpw3.org (Rob Warnock)
Date: Wed, 26 Mar 2008 05:46:03 -0500
Newsgroups: comp.lang.lisp
Message-ID: <AuKdndGwUPP2tHfanZ2dnUVZ_qSonZ2d@speakeasy.net>
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