From: ·················@gmail.com
Subject: lambda list question
Date: 
Message-ID: <d3e860a4-e0ba-4eb4-9ebd-7de1f6338ac3@c19g2000prf.googlegroups.com>
Greetings fellow Lispers,

In the following example:

CL-USER> (defun test (a b c &rest key-pairs &key x y z &allow-other-
keys)
	   (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-pairs=~A~%"
		   a b c x y z key-pairs))
TEST
CL-USER> (test 1 2 3 :x "x" :z "z" :foo "foo" :bar "bar")
a=1
b=2
c=3
x=x
y=NIL
z=z
key-pairs=(X x Z z FOO foo BAR bar)
NIL

I was surprised today that with TEST defined this way, KEY-PAIRS
contains all the keywords passed to TEST, including any declared in
the &KEY section.  I realize the hyperspec says this is by design.

Is there any way to write the definition of TEST so that KEY-PAIRS
does not contain the keys X, Y and Z?  Without explicitly removing
them in the function body of course ;-)

Thanks,

Anthony

From: alien_guy
Subject: Re: lambda list question
Date: 
Message-ID: <pan.2008.03.24.01.28.42@l.org>
On Sun, 23 Mar 2008 17:49:55 -0700, ·················@gmail.com wrote:

> Greetings fellow Lispers,
> 
> In the following example:
> 
> CL-USER> (defun test (a b c &rest key-pairs &key x y z &allow-other-
> keys)
> 	   (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-pairs=~A~%"
> 		   a b c x y z key-pairs))
>
> Is there any way to write the definition of TEST so that KEY-PAIRS does
> not contain the keys X, Y and Z?  Without explicitly removing them in
> the function body of course ;-)

No.
From: Rob Warnock
Subject: Re: lambda list question
Date: 
Message-ID: <T9CdncG88_ya03ranZ2dnUVZ_hWdnZ2d@speakeasy.net>
alien_guy <·@l.org> wrote:
+---------------
| ·················@gmail.com wrote:
| > Is there any way to write the definition of TEST so that KEY-PAIRS does
| > not contain the keys X, Y and Z?  Without explicitly removing them in
| > the function body of course ;-)
| 
| No.
+---------------

The same answer, a little less tersely:  ;-}

    http://alu.org/HyperSpec/Body/sec_3-4-1-4.html
    3.4.1.4 Specifiers for keyword parameters
    ...
    When keyword parameters are processed, the same arguments are
    processed that would be made into a list for a rest parameter.
    It is permitted to specify both &REST and &KEY. In this case the
    remaining arguments are used for both purposes; that is, all
    remaining arguments are made into a list for the rest parameter,
    and are also processed for the &KEY parameters.

Also note that <http://alu.org/HyperSpec/Body/sec_3-4-1.html>
"3.4.1 Ordinary Lambda Lists" requires that &REST come immediately
*before* &KEY [if both are present], so you can't get around it by
trying to manipulate the order or content of "the remaining arguments".


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Kent M Pitman
Subject: Re: lambda list question
Date: 
Message-ID: <ubq54f9xj.fsf@nhplace.com>
alien_guy <·@l.org> writes:

> On Sun, 23 Mar 2008 17:49:55 -0700, ·················@gmail.com wrote:
> 
> > Greetings fellow Lispers,
> > 
> > In the following example:
> > 
> > CL-USER> (defun test (a b c &rest key-pairs &key x y z &allow-other-
> > keys)
> > 	   (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-pairs=~A~%"
> > 		   a b c x y z key-pairs))
> >
> > Is there any way to write the definition of TEST so that KEY-PAIRS does
> > not contain the keys X, Y and Z?  Without explicitly removing them in
> > the function body of course ;-)
> 
> No.

Well... actually, ... not no.

You can remove them in the &aux list.

Strictly speaking, that's not the body. ;)

I don't recommend using &aux for much of any "normal" use, and so it comes
in handy for kludges like this under rare circumstances.
From: David Crawford
Subject: Re: lambda list question
Date: 
Message-ID: <0a83990e-b836-4476-8d6f-168272330080@x41g2000hsb.googlegroups.com>
On Mar 23, 8:49 pm, ··················@gmail.com"
<·················@gmail.com> wrote:
> Greetings fellow Lispers,
>
> In the following example:
>
> CL-USER> (defun test (a b c &rest key-pairs &key x y z &allow-other-
> keys)
>            (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-pairs=~A~%"
>                    a b c x y z key-pairs))
> TEST
> CL-USER> (test 1 2 3 :x "x" :z "z" :foo "foo" :bar "bar")
> a=1
> b=2
> c=3
> x=x
> y=NIL
> z=z
> key-pairs=(X x Z z FOO foo BAR bar)
> NIL
>
> I was surprised today that with TEST defined this way, KEY-PAIRS
> contains all the keywords passed to TEST, including any declared in
> the &KEY section.  I realize the hyperspec says this is by design.
>
> Is there any way to write the definition of TEST so that KEY-PAIRS
> does not contain the keys X, Y and Z?  Without explicitly removing
> them in the function body of course ;-)
>
> Thanks,
>
> Anthony

It seems like what you want is

(defun test (a b c &key x y z &rest key-pairs &allow-other-keys)
            (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-
pairs=~A~%"
                    a b c x y z key-pairs))

Which is completely untested, might not compile, etc, etc, etc.
From: Victor Kryukov
Subject: Re: lambda list question
Date: 
Message-ID: <m21w5zhi0b.fsf@gmail.com>
David Crawford <··············@gmail.com> writes:

> On Mar 23, 8:49 pm, ··················@gmail.com"
> <·················@gmail.com> wrote:
>> Greetings fellow Lispers,
>>
>> In the following example:
>>
>> CL-USER> (defun test (a b c &rest key-pairs &key x y z &allow-other-
>> keys)
>>            (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-pairs=~A~%"
>>                    a b c x y z key-pairs))
>> TEST
>> CL-USER> (test 1 2 3 :x "x" :z "z" :foo "foo" :bar "bar")
>> a=1
>> b=2
>> c=3
>> x=x
>> y=NIL
>> z=z
>> key-pairs=(X x Z z FOO foo BAR bar)
>> NIL
>>
>> I was surprised today that with TEST defined this way, KEY-PAIRS
>> contains all the keywords passed to TEST, including any declared in
>> the &KEY section.  I realize the hyperspec says this is by design.
>>
>> Is there any way to write the definition of TEST so that KEY-PAIRS
>> does not contain the keys X, Y and Z?  Without explicitly removing
>> them in the function body of course ;-)
>
> It seems like what you want is
>
> (defun test (a b c &key x y z &rest key-pairs &allow-other-keys)
>             (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-
> pairs=~A~%"
>                     a b c x y z key-pairs))
>
> Which is completely untested, might not compile, etc, etc, etc.

Indeed, it doesn't compile:

SBCL:
Execution of a form compiled with errors.
Form:
  #'(NAMED-LAMBDA TEST (A B C &KEY X Y Z &REST KEY-PAIRS &ALLOW-OTHER-KEYS)
                (BLOCK TEST
                  (FORMAT T a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-
pairs=~A~%
                          A B C X Y Z KEY-PAIRS)))
Compile-time error:
  misplaced &REST in lambda list: (A B C &KEY X Y Z &REST KEY-PAIRS
                                 &ALLOW-OTHER-KEYS)
   [Condition of type SB-INT:COMPILED-PROGRAM-ERROR]

CLISP:
*** - DEFUN: Lambda list marker &REST not allowed here.
The following restarts are available:
ABORT          :R1      ABORT

and such lambda-form is not allowed per CLHS:
http://www.lisp.org/HyperSpec/Body/sec_3-4-1.html

While do you post untested non-working code?

Regards,
Victor.

-- 
http://macrodefinition.blogspot.com
From: David Crawford
Subject: Re: lambda list question
Date: 
Message-ID: <4981aef8-772d-449b-b1f1-a5e0d372bbe5@m3g2000hsc.googlegroups.com>
On Mar 24, 6:30 pm, Victor Kryukov <··············@gmail.com> wrote:
> David Crawford <··············@gmail.com> writes:
> > On Mar 23, 8:49 pm, ··················@gmail.com"
> > <·················@gmail.com> wrote:
> >> Greetings fellow Lispers,
>
> >> In the following example:
>
> >> CL-USER> (defun test (a b c &rest key-pairs &key x y z &allow-other-
> >> keys)
> >>            (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-pairs=~A~%"
> >>                    a b c x y z key-pairs))
> >> TEST
> >> CL-USER> (test 1 2 3 :x "x" :z "z" :foo "foo" :bar "bar")
> >> a=1
> >> b=2
> >> c=3
> >> x=x
> >> y=NIL
> >> z=z
> >> key-pairs=(X x Z z FOO foo BAR bar)
> >> NIL
>
> >> I was surprised today that with TEST defined this way, KEY-PAIRS
> >> contains all the keywords passed to TEST, including any declared in
> >> the &KEY section.  I realize the hyperspec says this is by design.
>
> >> Is there any way to write the definition of TEST so that KEY-PAIRS
> >> does not contain the keys X, Y and Z?  Without explicitly removing
> >> them in the function body of course ;-)
>
> > It seems like what you want is
>
> > (defun test (a b c &key x y z &rest key-pairs &allow-other-keys)
> >             (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-
> > pairs=~A~%"
> >                     a b c x y z key-pairs))
>
> > Which is completely untested, might not compile, etc, etc, etc.
>
> Indeed, it doesn't compile:
>
> SBCL:
> Execution of a form compiled with errors.
> Form:
>   #'(NAMED-LAMBDA TEST (A B C &KEY X Y Z &REST KEY-PAIRS &ALLOW-OTHER-KEYS)
>                 (BLOCK TEST
>                   (FORMAT T a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-
> pairs=~A~%
>                           A B C X Y Z KEY-PAIRS)))
> Compile-time error:
>   misplaced &REST in lambda list: (A B C &KEY X Y Z &REST KEY-PAIRS
>                                  &ALLOW-OTHER-KEYS)
>    [Condition of type SB-INT:COMPILED-PROGRAM-ERROR]
>
> CLISP:
> *** - DEFUN: Lambda list marker &REST not allowed here.
> The following restarts are available:
> ABORT          :R1      ABORT
>
> and such lambda-form is not allowed per CLHS:http://www.lisp.org/HyperSpec/Body/sec_3-4-1.html
>
> While do you post untested non-working code?
>
> Regards,
> Victor.
>
> --http://macrodefinition.blogspot.com

It was mostly to see feel for what the "wouldn't it be nice if.."
meaning that he was trying to say was what I thought.  Although, while
I read Rob's post above, I must have been tired -- because if:

---
Also note that <http://alu.org/HyperSpec/Body/sec_3-4-1.html>
"3.4.1 Ordinary Lambda Lists" requires that &REST come immediately
*before* &KEY [if both are present], so you can't get around it by
trying to manipulate the order or content of "the remaining
arguments".
---

actually sank in I would've realized that that was the exact thing I
was about to (and stupidly did) write.  On the other hand at least I
had enough of a sense of there's probably a stinking good reason this
hasn't been mentioned yet ( .. it had .. ) to qualify it that it might
be wrong in multiple really bad ways.
From: Marco Antoniotti
Subject: Re: lambda list question
Date: 
Message-ID: <8a12f56f-1dbe-40f5-a0c8-45dc337c7ceb@a23g2000hsc.googlegroups.com>
On Mar 24, 2:49 am, ··················@gmail.com"
<·················@gmail.com> wrote:
> Greetings fellow Lispers,
>
> In the following example:
>
> CL-USER> (defun test (a b c &rest key-pairs &key x y z &allow-other-
> keys)
>            (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-pairs=~A~%"
>                    a b c x y z key-pairs))
> TEST
> CL-USER> (test 1 2 3 :x "x" :z "z" :foo "foo" :bar "bar")
> a=1
> b=2
> c=3
> x=x
> y=NIL
> z=z
> key-pairs=(X x Z z FOO foo BAR bar)
> NIL
>
> I was surprised today that with TEST defined this way, KEY-PAIRS
> contains all the keywords passed to TEST, including any declared in
> the &KEY section.  I realize the hyperspec says this is by design.
>
> Is there any way to write the definition of TEST so that KEY-PAIRS
> does not contain the keys X, Y and Z?  Without explicitly removing
> them in the function body of course ;-)
>

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))

This is because KEYS is actually a plist.  YMMV, you are destructively
modifying KEYS.  You may want to save it somewhere before REMFing.

Cheers
--
Marco
From: Marco Antoniotti
Subject: Re: lambda list question
Date: 
Message-ID: <4ea2c6f8-5301-457a-90b4-146ca8e64bd9@59g2000hsb.googlegroups.com>
On Mar 25, 7:55 am, Marco Antoniotti <·······@gmail.com> wrote:
> On Mar 24, 2:49 am, ··················@gmail.com"
>
>
>
> <·················@gmail.com> wrote:
> > Greetings fellow Lispers,
>
> > In the following example:
>
> > CL-USER> (defun test (a b c &rest key-pairs &key x y z &allow-other-
> > keys)
> >            (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-pairs=~A~%"
> >                    a b c x y z key-pairs))
> > TEST
> > CL-USER> (test 1 2 3 :x "x" :z "z" :foo "foo" :bar "bar")
> > a=1
> > b=2
> > c=3
> > x=x
> > y=NIL
> > z=z
> > key-pairs=(X x Z z FOO foo BAR bar)
> > NIL
>
> > I was surprised today that with TEST defined this way, KEY-PAIRS
> > contains all the keywords passed to TEST, including any declared in
> > the &KEY section.  I realize the hyperspec says this is by design.
>
> > Is there any way to write the definition of TEST so that KEY-PAIRS
> > does not contain the keys X, Y and Z?  Without explicitly removing
> > them in the function body of course ;-)
>
> 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))
>
> This is because KEYS is actually a plist.  YMMV, you are destructively
> modifying KEYS.  You may want to save it somewhere before REMFing.
>
> Cheers
> --
> Marco

Of course, this is "removing them in the function body", but it isn't
all that painful.

Cheers
--
Marco
From: Kent M Pitman
Subject: Re: lambda list question
Date: 
Message-ID: <umyomlvvd.fsf@nhplace.com>
Marco Antoniotti <·······@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))
> >
> > This is because KEYS is actually a plist.  YMMV, you are destructively
> > modifying KEYS.  You may want to save it somewhere before REMFing.
> >
> > Cheers
> > --
> > Marco
> 
> 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.  So the behavior of:

  (apply #'test1 '(:x 3 :y 4 :z 5))

is probably portably secure but

  (apply #'test1 '(:z 5 :y 4 :x 3))

or

  (apply #'test1 '(:a 1 :b 2 :x 3 :y 4 :z 5))

may not be.  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.

Part of the issue is that there was no "conservative" programming
style, since if you always copy the list, you were forcing consing in
implementations that don't need it, and if you didn't always copy the
list, you were risking a bad side-effect.  And there was no predicate
to dynamically tell you which to do, so you really had to know the code.

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.

Offhand I can't recall if it got "fixed", but I'm sure someone will
tell me.  I just figured it'd make interesting reading for history
buffs either way, since the situation arose out of a clash of good
intentions from both directions (to make the sharing of the list under
APPLY efficient, and yet to make &REST create first-class lists you
could play with using normal list operations, even ones with
side-effects).
From: Rob Warnock
Subject: Re: lambda list question
Date: 
Message-ID: <AuKdndGwUPP2tHfanZ2dnUVZ_qSonZ2d@speakeasy.net>
Kent M Pitman  <······@nhplace.com> wrote:
+---------------
| Marco Antoniotti <·······@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.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: ·················@gmail.com
Subject: Re: lambda list question
Date: 
Message-ID: <8ae32d69-265f-4044-a232-9db44638511b@e23g2000prf.googlegroups.com>
On Mar 25, 5:46 am, Marco Antoniotti <·······@gmail.com> wrote:
> On Mar 25, 7:55 am, Marco Antoniotti <·······@gmail.com> wrote:
>
>
>
> > On Mar 24, 2:49 am, ··················@gmail.com"
>
> > <·················@gmail.com> wrote:
> > > Greetings fellow Lispers,
>
> > > In the following example:
>
> > > CL-USER> (defun test (a b c &rest key-pairs &key x y z &allow-other-
> > > keys)
> > >            (format t "a=~A~%b=~A~%c=~A~%x=~A~%y=~A~%z=~A~%key-pairs=~A~%"
> > >                    a b c x y z key-pairs))
> > > TEST
> > > CL-USER> (test 1 2 3 :x "x" :z "z" :foo "foo" :bar "bar")
> > > a=1
> > > b=2
> > > c=3
> > > x=x
> > > y=NIL
> > > z=z
> > > key-pairs=(X x Z z FOO foo BAR bar)
> > > NIL
>
> > > I was surprised today that with TEST defined this way, KEY-PAIRS
> > > contains all the keywords passed to TEST, including any declared in
> > > the &KEY section.  I realize the hyperspec says this is by design.
>
> > > Is there any way to write the definition of TEST so that KEY-PAIRS
> > > does not contain the keys X, Y and Z?  Without explicitly removing
> > > them in the function body of course ;-)
>
> > 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))
>
> > This is because KEYS is actually a plist.  YMMV, you are destructively
> > modifying KEYS.  You may want to save it somewhere before REMFing.
>
> > Cheers
> > --
> > Marco
>
> Of course, this is "removing them in the function body", but it isn't
> all that painful.
>
> Cheers
> --
> Marco

This is exactly what I ended up doing, but I make a copy of keys
before removing.  Thank you and everyone else that responded!

Anthony
From: Edi Weitz
Subject: Re: lambda list question
Date: 
Message-ID: <uk5jq7e54.fsf@agharta.de>
On Tue, 25 Mar 2008 13:09:16 -0700 (PDT), ··················@gmail.com" <·················@gmail.com> wrote:

> This is exactly what I ended up doing, but I make a copy of keys
> before removing.

For removing the keys, this might be useful:

  http://groups.google.com/group/comp.lang.lisp/msg/2520fe9bc7749328

Edi.

-- 

European Common Lisp Meeting, Amsterdam, April 19/20, 2008

  http://weitz.de/eclm2008/

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Pascal Costanza
Subject: Re: lambda list question
Date: 
Message-ID: <64t7nrF2a0offU1@mid.individual.net>
Edi Weitz wrote:
> On Tue, 25 Mar 2008 13:09:16 -0700 (PDT), ··················@gmail.com" <·················@gmail.com> wrote:
> 
>> This is exactly what I ended up doing, but I make a copy of keys
>> before removing.
> 
> For removing the keys, this might be useful:
> 
>   http://groups.google.com/group/comp.lang.lisp/msg/2520fe9bc7749328

That's too complicated.

(loop for (key value) on plist by #'cddr
       when (member key keys-to-keep)
       collect key collect value)


Pascal

-- 
1st European Lisp Symposium (ELS'08)
http://prog.vub.ac.be/~pcostanza/els08/

My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rob Warnock
Subject: Re: lambda list question
Date: 
Message-ID: <nYqdnds0DtUltnfanZ2dnUVZ_umlnZ2d@speakeasy.net>
Pascal Costanza  <··@p-cos.net> wrote:
+---------------
| Edi Weitz wrote:
| >··················@gmail.com" <·················@gmail.com> wrote:
| >> This is exactly what I ended up doing, but I make a copy of keys
| >> before removing.
| > 
| > For removing the keys, this might be useful:
| >   http://groups.google.com/group/comp.lang.lisp/msg/2520fe9bc7749328
| 
| That's too complicated.
| (loop for (key value) on plist by #'cddr
|        when (member key keys-to-keep)
|        collect key collect value)
+---------------

Uh... But this assumes one knows KEYS-TO-KEEP! The original
problem statement gave a KEYS-TO-STRIP-OUT [not per se,
but implicitly, by naming them], not KEYS-TO-KEEP, with an
&ALLOW-OTHER-KEYS so *anything* could end up in the &REST list.
So I'd think you'd want to write it like this instead:

  (loop for (key value) on plist by #'cddr
         unless (member key keys-to-strip-out)
         collect key collect value)


-Rob

p.s. If KEYS-TO-STRIP-OUT were *huge*, one might want to use
a hash table for speed:

  (loop for (key value) on plist by #'cddr
         unless (gethash key keys-to-strip-out-table)
         collect key collect value)

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Thomas A. Russ
Subject: Re: lambda list question
Date: 
Message-ID: <ymi3aqepxxa.fsf@blackcat.isi.edu>
··················@gmail.com" <·················@gmail.com> writes:

> Greetings fellow Lispers,
> 
> In the following example:
> 
> CL-USER> (defun test (a b c &rest key-pairs &key x y z &allow-other-
> keys)
...
> I was surprised today that with TEST defined this way, KEY-PAIRS
> contains all the keywords passed to TEST, including any declared in
> the &KEY section.  I realize the hyperspec says this is by design.
> 
> Is there any way to write the definition of TEST so that KEY-PAIRS
> does not contain the keys X, Y and Z?  Without explicitly removing
> them in the function body of course ;-)

Nope.  You have to explicitly remove them from the &rest list yourself.
Of course, it's easy to write such a function, as others have pointed
out. 

Why do you want to remove them anyway?  There may be another solution
that meets your requirements.

-- 
Thomas A. Russ,  USC/Information Sciences Institute