From: Jimka
Subject: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <1163251132.938888.232070@i42g2000cwa.googlegroups.com>
I am writing a macro which takes a lambda-list as one of its arguments.

Inside the macro i want to delcare a function which has &rest arguments
but uses destructuring-bind to validate the argument list.
Is there a way to keep tell the compiler to ignore the fact that i'm
binding
variables and never using them when i do not even know the names
of the variables i'm not using?

destructuring-bind should have the nice side effect of triggering
a runtime error if the function is called with incompatible arguments.
E.g., if lambda-list is (a b &key foo) but the function gets called
with
(1 2 3) or (1 2 :bar 3), then destructuring-bind should trigger an
error.
But if called with (1 2) or (1 2 :foo 3), then dispatch should get
called
happily with that list as its second argument.

Any suggestions?


(defmacro def-pap-fun (name lambda-list &rest body)
  `(let ((pap-function (make-instance 'pap-function :name ',name
:lambda-list ',lambda-list)))
     (add-pap ,name ,lambda-list t
	      ,@body)
     (defun ,name (&rest args)
       (destructuring-bind ,lambda-list args
	 nil) ;;;<<<<----- here i am not using any of lambda-list
       (dispatch pap-function args))))

From: Pascal Costanza
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <4rm1cjFrpbcaU1@mid.individual.net>
Jimka wrote:
> I am writing a macro which takes a lambda-list as one of its arguments.
> 
> Inside the macro i want to delcare a function which has &rest arguments
> but uses destructuring-bind to validate the argument list.
> Is there a way to keep tell the compiler to ignore the fact that i'm
> binding
> variables and never using them when i do not even know the names
> of the variables i'm not using?
> 
> destructuring-bind should have the nice side effect of triggering
> a runtime error if the function is called with incompatible arguments.
> E.g., if lambda-list is (a b &key foo) but the function gets called
> with
> (1 2 3) or (1 2 :bar 3), then destructuring-bind should trigger an
> error.
> But if called with (1 2) or (1 2 :foo 3), then dispatch should get
> called
> happily with that list as its second argument.
> 
> Any suggestions?

As far as I know (and I have looked very hard ;), there is no way to 
achieve this. You have to parse the lambda list to find the variable 
names, and then use an ignore declaration with those names.

Unfortunately, parsing lambda lists means that you have to deal with 
many special cases. :(


> (defmacro def-pap-fun (name lambda-list &rest body)
>   `(let ((pap-function (make-instance 'pap-function :name ',name
> :lambda-list ',lambda-list)))
>      (add-pap ,name ,lambda-list t
> 	      ,@body)
>      (defun ,name (&rest args)
>        (destructuring-bind ,lambda-list args
> 	 nil) ;;;<<<<----- here i am not using any of lambda-list
>        (dispatch pap-function args))))


Pascal

-- 
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: Jimka
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <1163252036.307218.272210@f16g2000cwb.googlegroups.com>
Is the compiler allowed to ignore my entire destructuring-bind since
i'm not doing anything with the parameters?   This would seem like
a compiler bug, because simply because the variables are not
explicitly used does not mean there are no important side effects,
namely the rasing of runtime errors if the parameters do not match
the arguments.
-jim


Pascal Costanza wrote:
> Jimka wrote:
> > I am writing a macro which takes a lambda-list as one of its arguments.
> >
> > Inside the macro i want to delcare a function which has &rest arguments
> > but uses destructuring-bind to validate the argument list.
> > Is there a way to keep tell the compiler to ignore the fact that i'm
> > binding
> > variables and never using them when i do not even know the names
> > of the variables i'm not using?
> >
> > destructuring-bind should have the nice side effect of triggering
> > a runtime error if the function is called with incompatible arguments.
> > E.g., if lambda-list is (a b &key foo) but the function gets called
> > with
> > (1 2 3) or (1 2 :bar 3), then destructuring-bind should trigger an
> > error.
> > But if called with (1 2) or (1 2 :foo 3), then dispatch should get
> > called
> > happily with that list as its second argument.
> >
> > Any suggestions?
>
> As far as I know (and I have looked very hard ;), there is no way to
> achieve this. You have to parse the lambda list to find the variable
> names, and then use an ignore declaration with those names.
>
> Unfortunately, parsing lambda lists means that you have to deal with
> many special cases. :(
>
>
> > (defmacro def-pap-fun (name lambda-list &rest body)
> >   `(let ((pap-function (make-instance 'pap-function :name ',name
> > :lambda-list ',lambda-list)))
> >      (add-pap ,name ,lambda-list t
> > 	      ,@body)
> >      (defun ,name (&rest args)
> >        (destructuring-bind ,lambda-list args
> > 	 nil) ;;;<<<<----- here i am not using any of lambda-list
> >        (dispatch pap-function args))))
>
>
> Pascal
>
> --
> 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: Pascal Costanza
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <4rm3k9Frj96fU1@mid.individual.net>
Misunderstanding: When I said "there is no way to achieve this", I meant 
that there is no way to tell the compiler to ignore all unused variables 
in some lexical scope.

The compiler is indeed not allowed to ignore a destructuring-bind with 
an empty body.

Maybe the following hack provides a usable workaround:

(handler-bind ((warning #'muffle-warning))
   (eval `(destructuring-bind ,lambda-list ,args)))


[Untested.]

Pascal

Jimka wrote:
> Is the compiler allowed to ignore my entire destructuring-bind since
> i'm not doing anything with the parameters?   This would seem like
> a compiler bug, because simply because the variables are not
> explicitly used does not mean there are no important side effects,
> namely the rasing of runtime errors if the parameters do not match
> the arguments.
> -jim
> 
> 
> Pascal Costanza wrote:
>> Jimka wrote:
>>> I am writing a macro which takes a lambda-list as one of its arguments.
>>>
>>> Inside the macro i want to delcare a function which has &rest arguments
>>> but uses destructuring-bind to validate the argument list.
>>> Is there a way to keep tell the compiler to ignore the fact that i'm
>>> binding
>>> variables and never using them when i do not even know the names
>>> of the variables i'm not using?
>>>
>>> destructuring-bind should have the nice side effect of triggering
>>> a runtime error if the function is called with incompatible arguments.
>>> E.g., if lambda-list is (a b &key foo) but the function gets called
>>> with
>>> (1 2 3) or (1 2 :bar 3), then destructuring-bind should trigger an
>>> error.
>>> But if called with (1 2) or (1 2 :foo 3), then dispatch should get
>>> called
>>> happily with that list as its second argument.
>>>
>>> Any suggestions?
>> As far as I know (and I have looked very hard ;), there is no way to
>> achieve this. You have to parse the lambda list to find the variable
>> names, and then use an ignore declaration with those names.
>>
>> Unfortunately, parsing lambda lists means that you have to deal with
>> many special cases. :(
>>
>>
>>> (defmacro def-pap-fun (name lambda-list &rest body)
>>>   `(let ((pap-function (make-instance 'pap-function :name ',name
>>> :lambda-list ',lambda-list)))
>>>      (add-pap ,name ,lambda-list t
>>> 	      ,@body)
>>>      (defun ,name (&rest args)
>>>        (destructuring-bind ,lambda-list args
>>> 	 nil) ;;;<<<<----- here i am not using any of lambda-list
>>>        (dispatch pap-function args))))
>>
>> Pascal
>>
>> --
>> My website: http://p-cos.net
>> Common Lisp Document Repository: http://cdr.eurolisp.org
>> Closer to MOP & ContextL: http://common-lisp.net/project/closer/
> 


-- 
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: Jimka
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <1163254677.116949.278630@m73g2000cwd.googlegroups.com>
Hi Pascal, does your closer package provide a usable lambda list
parser?
You probably had to write one and make it work on lots of different
implementations, right?
-jim


Pascal Costanza wrote:
> Misunderstanding: When I said "there is no way to achieve this", I meant
> that there is no way to tell the compiler to ignore all unused variables
> in some lexical scope.
>
> The compiler is indeed not allowed to ignore a destructuring-bind with
> an empty body.
>
> Maybe the following hack provides a usable workaround:
>
> (handler-bind ((warning #'muffle-warning))
>    (eval `(destructuring-bind ,lambda-list ,args)))
>
>
> [Untested.]
>
> Pascal
>
> Jimka wrote:
> > Is the compiler allowed to ignore my entire destructuring-bind since
> > i'm not doing anything with the parameters?   This would seem like
> > a compiler bug, because simply because the variables are not
> > explicitly used does not mean there are no important side effects,
> > namely the rasing of runtime errors if the parameters do not match
> > the arguments.
> > -jim
> >
> >
> > Pascal Costanza wrote:
> >> Jimka wrote:
> >>> I am writing a macro which takes a lambda-list as one of its arguments.
> >>>
> >>> Inside the macro i want to delcare a function which has &rest arguments
> >>> but uses destructuring-bind to validate the argument list.
> >>> Is there a way to keep tell the compiler to ignore the fact that i'm
> >>> binding
> >>> variables and never using them when i do not even know the names
> >>> of the variables i'm not using?
> >>>
> >>> destructuring-bind should have the nice side effect of triggering
> >>> a runtime error if the function is called with incompatible arguments.
> >>> E.g., if lambda-list is (a b &key foo) but the function gets called
> >>> with
> >>> (1 2 3) or (1 2 :bar 3), then destructuring-bind should trigger an
> >>> error.
> >>> But if called with (1 2) or (1 2 :foo 3), then dispatch should get
> >>> called
> >>> happily with that list as its second argument.
> >>>
> >>> Any suggestions?
> >> As far as I know (and I have looked very hard ;), there is no way to
> >> achieve this. You have to parse the lambda list to find the variable
> >> names, and then use an ignore declaration with those names.
> >>
> >> Unfortunately, parsing lambda lists means that you have to deal with
> >> many special cases. :(
> >>
> >>
> >>> (defmacro def-pap-fun (name lambda-list &rest body)
> >>>   `(let ((pap-function (make-instance 'pap-function :name ',name
> >>> :lambda-list ',lambda-list)))
> >>>      (add-pap ,name ,lambda-list t
> >>> 	      ,@body)
> >>>      (defun ,name (&rest args)
> >>>        (destructuring-bind ,lambda-list args
> >>> 	 nil) ;;;<<<<----- here i am not using any of lambda-list
> >>>        (dispatch pap-function args))))
> >>
> >> Pascal
> >>
> >> --
> >> My website: http://p-cos.net
> >> Common Lisp Document Repository: http://cdr.eurolisp.org
> >> Closer to MOP & ContextL: http://common-lisp.net/project/closer/
> >
>
>
> --
> 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: Pascal Costanza
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <4rm6e4FrujjaU1@mid.individual.net>
Jimka wrote:
> Hi Pascal, does your closer package provide a usable lambda list
> parser?
> You probably had to write one and make it work on lots of different
> implementations, right?

In the published code, I only use ad hoc "parsers" that do exactly what 
is required in the respective situation, and nothing else. So they are 
unfortunately not very reusable.

I have experimented with some ideas for reusable lambda list parsers, 
but haven't come up with something that I am sufficiently happy with and 
that I would like to make publicly available.

If you're really very interested, I can send you what I have privately, 
but don't hope for something that's immediately usable.

The various open source CL implementations must have lambda list 
parsers, maybe there is something to look for.


Pascal

-- 
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: Pascal Bourguignon
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <87hcx5n9q0.fsf@thalassa.informatimago.com>
Pascal Costanza <··@p-cos.net> writes:

> Jimka wrote:
>> Hi Pascal, does your closer package provide a usable lambda list
>> parser?
>> You probably had to write one and make it work on lots of different
>> implementations, right?
>
> In the published code, I only use ad hoc "parsers" that do exactly
> what is required in the respective situation, and nothing else. So
> they are unfortunately not very reusable.
>
> I have experimented with some ideas for reusable lambda list parsers,
> but haven't come up with something that I am sufficiently happy with
> and that I would like to make publicly available.
>
> If you're really very interested, I can send you what I have
> privately, but don't hope for something that's immediately usable.
>
> The various open source CL implementations must have lambda list
> parsers, maybe there is something to look for.

I've got a lambda list parser in:

http://www.informatimago.com/develop/lisp/index.html
http://darcs.informatimago.com/darcs/public/lisp/common-lisp/source.lisp

But note that I don't treat implementation specific lambda list
keywords (but those can be used only with macros, so this won't be a
problem for you).

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

THIS IS A 100% MATTER PRODUCT: In the unlikely event that this
merchandise should contact antimatter in any form, a catastrophic
explosion will result.
From: Harald Hanche-Olsen
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <pco1woa58c7.fsf@shuttle.math.ntnu.no>
+ "Jimka" <·····@rdrop.com>:

| Is there a way to keep tell the compiler to ignore the fact that i'm
| binding variables and never using them when i do not even know the
| names of the variables i'm not using?

Will an IGNORABLE declaration work for you?
Or maybe I missed your whole point ...

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
  when there is no ground whatsoever for supposing it is true.
  -- Bertrand Russell
From: Jimka
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <1163257122.796908.247440@i42g2000cwa.googlegroups.com>
If you have an idea it would be great to hear Harald,  what should i
make IGNORABLE?
If lambda-list is (a b) then i want a and to be ignorable,
If lambda-list is (a b &rest c) then i want a b and c to be ignorable,
If lambda-list is (a b &key (c 100) &rest d) then i want a b c and d to
be ignorable.
But the problem is lambda-list is potentially different every time the
macro is expanded.
So the problem is how to calculate the list of variables to ignore.
Any ideas Harald?

kind   regards
-jim

Harald Hanche-Olsen wrote:
> + "Jimka" <·····@rdrop.com>:
>
> | Is there a way to keep tell the compiler to ignore the fact that i'm
> | binding variables and never using them when i do not even know the
> | names of the variables i'm not using?
>
> Will an IGNORABLE declaration work for you?
> Or maybe I missed your whole point ...
>
> --
> * Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
> - It is undesirable to believe a proposition
>   when there is no ground whatsoever for supposing it is true.
>   -- Bertrand Russell
From: Carl Taylor
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <g3n5h.45295$Fi1.29850@bgtnsc05-news.ops.worldnet.att.net>
Jimka wrote:

> If lambda-list is (a b) then i want a and to be ignorable,
> If lambda-list is (a b &rest c) then i want a b and c to be ignorable,
> If lambda-list is (a b &key (c 100) &rest d) then i want a b c and d
> to be ignorable.
> But the problem is lambda-list is potentially different every time the
> macro is expanded.
> So the problem is how to calculate the list of variables to ignore.

[...]

Do you mean something like this?

Carl Taylor



(defun flatten (in-list &optional accumulator)
  "From: Norvig's PAIP."
  (cond ((null in-list) accumulator)
        ((atom in-list) (cons in-list accumulator))
        (t
         (flatten (car in-list)
                  (flatten (cdr in-list) accumulator)))))



(defmacro foo (name lambda-list)
  (let ((l-arg-list
         (delete-if #'(lambda (x) (char= #\& (schar (string x) 0)))
                       (delete-if (complement #'symbolp)
                                    (flatten lambda-list)))))
     `(defun ,name (&rest args)
        (destructuring-bind ,l-arg-list args
          (declare (ignore ,@l-arg-list))))))



(pprint (macroexpand '(foo baz (a b))))
(pprint (macroexpand '(foo baz (a b &rest c))))
(pprint (macroexpand '(foo baz (a b &key (c 100) &rest d))))
From: John Thingstad
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <op.tiu0cnrlpqzri1@pandora.upc.no>
On Sat, 11 Nov 2006 15:58:42 +0100, Jimka <·····@rdrop.com> wrote:


define-compiler-macro takes care of decisions that must be delayed to
compile time.


-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Jimka
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <1163268485.590550.201090@m7g2000cwm.googlegroups.com>
Interesting John,

So how can i use define-compiler-macro to declare
ignorable the variables declared  in the lambda-list variable?

 (defmacro foo (lambda-list fun)
     `(defun bar (@rest args)
	 (destructuring-bind ,lambda-list args
	   nil)
	 (apply ,fun args)))


John Thingstad wrote:
> On Sat, 11 Nov 2006 15:58:42 +0100, Jimka <·····@rdrop.com> wrote:
>
>
> define-compiler-macro takes care of decisions that must be delayed to
> compile time.
>
>
> --
> Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Harald Hanche-Olsen
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <pcowt614n54.fsf@shuttle.math.ntnu.no>
+ "Jimka" <·····@rdrop.com>:

| If you have an idea it would be great to hear Harald, what should i
| make IGNORABLE?

My response was apparently based on a misreading of your original
post, as explained in a followup to Pascal Costanza.  My entire point
was to point out the difference between IGNORE and IGNORABLE:  With
the latter, you don't need to know which variables you're not using,
but you do of course need to know which variables are being bound.
Since I thought your problem was of the former kind rather than the
latter, my response was reasonable.

Now I see that others have provided substantial help in the meantime,
so my input is certainly not needed.  But I would have appreciated it
if you had laid off the sarcasm.  It was uncalled for.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
  when there is no ground whatsoever for supposing it is true.
  -- Bertrand Russell
From: Pascal Costanza
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <4rm6huFrujjaU2@mid.individual.net>
Harald Hanche-Olsen wrote:
> + "Jimka" <·····@rdrop.com>:
> 
> | Is there a way to keep tell the compiler to ignore the fact that i'm
> | binding variables and never using them when i do not even know the
> | names of the variables i'm not using?
> 
> Will an IGNORABLE declaration work for you?
> Or maybe I missed your whole point ...

For an ignorable declaration, you need the names of the variables that 
should be ignorable. In the original code, the lambda list isn't 
destructured, though, so it's not obvious what the variable names are.

A (declare (ignorable *)) form would indeed sometimes be useful to 
suppress warnings about any unused variables.


Pascal

-- 
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: Harald Hanche-Olsen
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <pco1wo9624j.fsf@shuttle.math.ntnu.no>
+ Pascal Costanza <··@p-cos.net>:

| Harald Hanche-Olsen wrote:
|> + "Jimka" <·····@rdrop.com>:
|> | Is there a way to keep tell the compiler to ignore the fact that
|> i'm
|> | binding variables and never using them when i do not even know the
|> | names of the variables i'm not using?
|> Will an IGNORABLE declaration work for you?
|> Or maybe I missed your whole point ...
|
| For an ignorable declaration, you need the names of the variables that
| should be ignorable. In the original code, the lambda list isn't
| destructured, though, so it's not obvious what the variable names are.

Ah.  That was the point I missed.  I thought the problem was that the
OP didn't want to parse the body for unused variables.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
  when there is no ground whatsoever for supposing it is true.
  -- Bertrand Russell
From: Wade Humeniuk
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <Tgp5h.2752$ae6.722@clgrps13>
Jimka wrote:
> I am writing a macro which takes a lambda-list as one of its arguments.
> 
> Inside the macro i want to delcare a function which has &rest arguments
> but uses destructuring-bind to validate the argument list.
> Is there a way to keep tell the compiler to ignore the fact that i'm
> binding
> variables and never using them when i do not even know the names
> of the variables i'm not using?
> 
> destructuring-bind should have the nice side effect of triggering
> a runtime error if the function is called with incompatible arguments.
> E.g., if lambda-list is (a b &key foo) but the function gets called
> with
> (1 2 3) or (1 2 :bar 3), then destructuring-bind should trigger an
> error.
> But if called with (1 2) or (1 2 :foo 3), then dispatch should get
> called
> happily with that list as its second argument.
> 
> Any suggestions?

(defmacro def-pap-fun (name lambda-list &rest body)
   `(let ((pap-function (make-instance 'pap-function :name ',name
:lambda-list ',lambda-list)))
      (add-pap ,name ,lambda-list t
	      ,@body)
      (defun ,name (&rest args)
        (destructuring-bind ,lambda-list args
          (declare (ignorable ,@(mapcar (lambda (arg)
                                          (etypecase arg
                                            (cons (car arg))
                                            (atom arg)))
                                        (remove-if
                                         (lambda (arg)
                                           (member arg '(&key &rest)))
                                         lambda-list))))
	 nil) ;;;<<<<----- here i am not using any of lambda-list
        (dispatch pap-function args))))

CL-USER 3 > (pprint (macroexpand '(def-pap-fun test (a b &key (c 10)) nil)))

(LET ((PAP-FUNCTION
        (MAKE-INSTANCE 'PAP-FUNCTION
                       :NAME
                       'TEST
                       :LAMBDA-LIST
                       '(A B &KEY (C 10)))))
   (ADD-PAP TEST (A B &KEY (C 10)) T NIL)
   (DEFUN TEST (&REST ARGS)
     (DESTRUCTURING-BIND (A B &KEY (C 10)) ARGS (DECLARE (IGNORABLE A B C)) NIL)
     (DISPATCH PAP-FUNCTION ARGS)))

CL-USER 4 >

Wade
From: Jimka
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <1163277046.861963.58730@e3g2000cwe.googlegroups.com>
Hi Wade, i think this is on the right track but not quite there.
But it fails for the following

(pprint (macroexpand '(def-pap-fun test (a b &key ((:c x) 10 used))
nil)))

(LET ((PAP-FUNCTION
       (MAKE-INSTANCE 'PAP-FUNCTION
                      :NAME
                      'TEST
                      :LAMBDA-LIST
                      '(A B &KEY ((:C X) 10 USED)))))
  (ADD-PAP TEST (A B &KEY ((:C X) 10 USED)) T NIL)
  (DEFUN TEST (&REST ARGS)
    (DESTRUCTURING-BIND
        (A B &KEY ((:C X) 10 USED))
        ARGS
      (DECLARE (IGNORABLE A B (:C X))) ;;<<< it should be ignoring X
and USED not (:C X)
      NIL)
    (DISPATCH PAP-FUNCTION ARGS)))
From: Wade Humeniuk
Subject: Re: how to declare ignorable in destructuring-bind
Date: 
Message-ID: <uur5h.2775$ae6.398@clgrps13>
Jimka wrote:
> Hi Wade, i think this is on the right track but not quite there.
> But it fails for the following
> 
> (pprint (macroexpand '(def-pap-fun test (a b &key ((:c x) 10 used))
> nil)))
> 
> (LET ((PAP-FUNCTION
>        (MAKE-INSTANCE 'PAP-FUNCTION
>                       :NAME
>                       'TEST
>                       :LAMBDA-LIST
>                       '(A B &KEY ((:C X) 10 USED)))))
>   (ADD-PAP TEST (A B &KEY ((:C X) 10 USED)) T NIL)
>   (DEFUN TEST (&REST ARGS)
>     (DESTRUCTURING-BIND
>         (A B &KEY ((:C X) 10 USED))
>         ARGS
>       (DECLARE (IGNORABLE A B (:C X))) ;;<<< it should be ignoring X
> and USED not (:C X)
>       NIL)
>     (DISPATCH PAP-FUNCTION ARGS)))
> 

There is nothing magic going on with macros, just modify it ...
(Of course the macro could be written with more extensive
error checking)

(defmacro def-pap-fun (name lambda-list &rest body)
   `(let ((pap-function (make-instance 'pap-function :name ',name
:lambda-list ',lambda-list)))
      (add-pap ,name ,lambda-list t
           ,@body)
      (defun ,name (&rest args)
        (destructuring-bind ,lambda-list args
          (declare (ignorable ,@(mapcan (lambda (arg)
                                          (etypecase arg
                                            (cons
                                             (destructuring-bind (var init &optional pred)
                                                 arg
                                               (declare (ignore init))
                                               (when (consp var) (setf var (cadr var)))
                                               (if pred (list var pred)
                                                 (list var))))
                                            (atom (list arg))))
                                        (remove-if
                                         (lambda (arg)
                                           (member arg '(&key &rest)))
                                         lambda-list))))
      nil) ;;;<<<<----- here i am not using any of lambda-list
        (dispatch pap-function args))))


CL-USER 5 > (pprint (macroexpand '(def-pap-fun test (a b &key ((:c x) 10 used))
nil)))

(LET ((PAP-FUNCTION
        (MAKE-INSTANCE 'PAP-FUNCTION
                       :NAME
                       'TEST
                       :LAMBDA-LIST
                       '(A B &KEY ((:C X) 10 USED)))))
   (ADD-PAP TEST (A B &KEY ((:C X) 10 USED)) T NIL)
   (DEFUN TEST (&REST ARGS)
     (DESTRUCTURING-BIND (A B &KEY ((:C X) 10 USED)) ARGS
       (DECLARE (IGNORABLE A B X USED))
       NIL)
     (DISPATCH PAP-FUNCTION ARGS)))

CL-USER 6 >