From: lbolla on
Hi all,
I have a macro that defines functions, like this:

(defmacro my-defun ((name &rest rest))
`(defun ,name ()
(list ,@rest)))

and I want to call it many time, with different arguments, like that:
(my-defun (f1 1))
(my-defun (f2 2))
(my-defun (f3 3))

I'd like to use mapcar, like this:
(mapcar #'my-defun '((f1 1) (f2 2) (f3 3))) ; error! my-defun is not a
function

but this does not work, because my-defun is not a function.
How would you do?
From: Pascal J. Bourguignon on
lbolla <lbolla(a)gmail.com> writes:

> Hi all,
> I have a macro that defines functions, like this:
>
> (defmacro my-defun ((name &rest rest))
> `(defun ,name ()
> (list ,@rest)))
>
> and I want to call it many time, with different arguments, like that:
> (my-defun (f1 1))
> (my-defun (f2 2))
> (my-defun (f3 3))
>
> I'd like to use mapcar, like this:
> (mapcar #'my-defun '((f1 1) (f2 2) (f3 3))) ; error! my-defun is not a
> function
>
> but this does not work, because my-defun is not a function.
> How would you do?

Make it a function!

(defun my-defun* (nr)
(destructuring-bind (name &rest rest) nr
(setf (fdefinition name) (compile nil `(lambda () (block ,name (list ,@rest)))))
name))

(mapcar (function funcall) (mapcar (function my-defun*) '((f1 1) (f2 1 2) (f3 1 2 3))))
--> ((1) (1 2) (1 2 3))

--
__Pascal Bourguignon__ http://www.informatimago.com/
From: Alessio Stalla on
On Jul 29, 5:22 pm, lbolla <lbo...(a)gmail.com> wrote:
> Hi all,
> I have a macro that defines functions, like this:
>
> (defmacro my-defun ((name &rest rest))
>   `(defun ,name ()
>          (list ,@rest)))
>
> and I want to call it many time, with different arguments, like that:
> (my-defun (f1 1))
> (my-defun (f2 2))
> (my-defun (f3 3))
>
> I'd like to use mapcar, like this:
> (mapcar #'my-defun '((f1 1) (f2 2) (f3 3))) ; error! my-defun is not a
> function
>
> but this does not work, because my-defun is not a function.
> How would you do?

There's more than one way to do it, and with different semantics.
Interpreting strictly what you said, you are asking how to apply a
macro function *at runtime* on a sequence of expressions that
represent invocations of that macro, obtaining a list of forms, which
are the result of macroexpansion on each input expression. I'll
assume, however, that you want to apply a macro to multiple forms *at
compile time*, which is probably what you intended to do. Since you
want it to happen at compile time, you need to write a macro for it,
for example:

(defmacro generate-calls (operator &rest arglists)
`(progn
,@(mapcar (lambda (arglist) `(,operator ,@arglist)) arglists)))

and use it like this:

(generate-calls my-defun (f1 1) (f2 2) (f3 3))

in fact, (macroexpand '(generate-calls my-defun (f1 1) (f2 2) (f3 3)))
==> (PROGN (MY-DEFUN F1 1) (MY-DEFUN F2 2) (MY-DEFUN F3 3))

hth,
Alessio
From: Peter Keller on
Pascal J. Bourguignon <pjb(a)informatimago.com> wrote:
> lbolla <lbolla(a)gmail.com> writes:
>
>> Hi all,
>> I have a macro that defines functions, like this:
>>
>> (defmacro my-defun ((name &rest rest))
>> `(defun ,name ()
>> (list ,@rest)))
>>
>> and I want to call it many time, with different arguments, like that:
>> (my-defun (f1 1))
>> (my-defun (f2 2))
>> (my-defun (f3 3))
>>
>> I'd like to use mapcar, like this:
>> (mapcar #'my-defun '((f1 1) (f2 2) (f3 3))) ; error! my-defun is not a
>> function
>>
>> but this does not work, because my-defun is not a function.
>> How would you do?
>
> Make it a function!
>
> (defun my-defun* (nr)
> (destructuring-bind (name &rest rest) nr
> (setf (fdefinition name) (compile nil `(lambda () (block ,name (list ,@rest)))))
> name))
>
> (mapcar (function funcall) (mapcar (function my-defun*) '((f1 1) (f2 1 2) (f3 1 2 3))))
> --> ((1) (1 2) (1 2 3))
>

Although, if I understand correctly, and correct me if I don't, that isn't
exactly the same thing because compile enforces a NIL lexical environment.

-pete
From: lbolla on
On 29 July, 16:38, p...(a)informatimago.com (Pascal J. Bourguignon)
wrote:
> lbolla <lbo...(a)gmail.com> writes:
> > Hi all,
> > I have a macro that defines functions, like this:
>
> > (defmacro my-defun ((name &rest rest))
> >   `(defun ,name ()
> >     (list ,@rest)))
>
> > and I want to call it many time, with different arguments, like that:
> > (my-defun (f1 1))
> > (my-defun (f2 2))
> > (my-defun (f3 3))
>
> > I'd like to use mapcar, like this:
> > (mapcar #'my-defun '((f1 1) (f2 2) (f3 3))) ; error! my-defun is not a
> > function
>
> > but this does not work, because my-defun is not a function.
> > How would you do?
>
> Make it a function!
>
> (defun my-defun* (nr)
>   (destructuring-bind (name &rest rest) nr
>     (setf (fdefinition name) (compile nil `(lambda () (block ,name (list ,@rest)))))
>     name))
>
> (mapcar (function funcall) (mapcar (function my-defun*)  '((f1 1) (f2 1 2) (f3 1 2 3))))
> --> ((1) (1 2) (1 2 3))
>
> --
> __Pascal Bourguignon__                    http://www.informatimago.com/

Thanks a lot!
Very instructive, indeed.
L.
 |  Next  |  Last
Pages: 1 2 3
Prev: ABCL 0.21 released
Next: Do we need a "Stevens" book?