From: rock69
Subject: Mutually recursive (local) macros
Date: 
Message-ID: <19b43493-3cbf-418c-b1b1-68c803a1269f@k30g2000hse.googlegroups.com>
I ask this just out of sheer curiosity and for no specific (at least
at the moment) application purpose. I know it's possible to define
recursive macros globally with DEFMACRO in a straightforward fashion,
but I also understand that you can't do that locally with MACROLET
because the latter behaves (just an analogy) like FLET rather than
LABELS (ref. Paul Graham ANSI CL or the HyperSpec). So you can't
write, I immagine, things like mutually (local) recursive macros with
something like MACROLET.

I wonder why such a possibility, at least in principle, was not taken
into account. Perhaps it's not considered useful or, quite possibly,
it could be very hard or even impossible to achieve. I'm very curious
as to why this is so in the standard, and if it is at all possible,
theoretically, to write (with defmacro for instance) an alternative to
MACROLET that is more like LABELS (again just an analogy of course).

From: Slobodan Blazeski
Subject: Re: Mutually recursive (local) macros
Date: 
Message-ID: <67cce27c-5e00-40ba-aade-9377cfde7951@34g2000hsh.googlegroups.com>
On Aug 11, 11:23 am, rock69 <···········@gmail.com> wrote:
> I ask this just out of sheer curiosity and for no specific (at least
> at the moment) application purpose. I know it's possible to define
> recursive macros globally with DEFMACRO in a straightforward fashion,
> but I also understand that you can't do that locally with MACROLET
> because the latter behaves (just an analogy) like FLET rather than
> LABELS (ref. Paul Graham ANSI CL or the HyperSpec). So you can't
> write, I immagine, things like mutually (local) recursive macros with
> something like MACROLET.
>
> I wonder why such a possibility, at least in principle, was not taken
> into account. Perhaps it's not considered useful or, quite possibly,
> it could be very hard or even impossible to achieve.
I don't know how useful would it be but I'm pretty sure it's not hard
to achieve.
You only need lambda and assignment operator, + access to the
enviroment, that implementation has.
(let ((x 1) (y 2))
  ...
<=>
(lambda (x y)
  (setf x 1 y 2)
  ....

(letrec ((x (y 2))
         (y (x 3))) ; just for demonstration
 ...
(lambda (x y)
  (begin
   (set! x (lambda () (y 2)))
   (set! y (lambda () (x 3)))
...
To make something macro you only need a control of evaluation of
passed parameters. Maybe some function like lazy .
This is just my humble opinion I'm really new to implementing.

> I'm very curious
> as to why this is so in the standard, and if it is at all possible,
> theoretically, to write (with defmacro for instance) an alternative to
> MACROLET that is more like LABELS (again just an analogy of course).
From: Pascal Costanza
Subject: Re: Mutually recursive (local) macros
Date: 
Message-ID: <6gam19Fetmg4U1@mid.individual.net>
rock69 wrote:
> I ask this just out of sheer curiosity and for no specific (at least
> at the moment) application purpose. I know it's possible to define
> recursive macros globally with DEFMACRO in a straightforward fashion,
> but I also understand that you can't do that locally with MACROLET
> because the latter behaves (just an analogy) like FLET rather than
> LABELS (ref. Paul Graham ANSI CL or the HyperSpec). So you can't
> write, I immagine, things like mutually (local) recursive macros with
> something like MACROLET.
> 
> I wonder why such a possibility, at least in principle, was not taken
> into account. Perhaps it's not considered useful or, quite possibly,
> it could be very hard or even impossible to achieve. I'm very curious
> as to why this is so in the standard, and if it is at all possible,
> theoretically, to write (with defmacro for instance) an alternative to
> MACROLET that is more like LABELS (again just an analogy of course).

You're wrong, it's actually the other way around: MACROLET is recursive 
by default, and there is no non-recursive version available. To wit:

(macrolet ((foo (arg) (if (null arg) '() `(bar ,arg)))
            (bar (arg) (if (null arg) '() `(foo nil))))
   (foo 5))

=> NIL

So FOO expands into an invocation of BAR, which is still in scope.

You can probably hack something to get non-recursive behavior (like LET, 
unlike LABELS) by using MACROEXPAND and environment objects explicitly, 
but it's not straightforward.

My guess is that it was simply not well understood that it could be 
useful to have both variants. Common Lisp was the first Lisp dialect to 
have local macro definitions, but didn't see a lot of changes after the 
initial design (unlike what happened in Scheme macro systems).


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 J. Bourguignon
Subject: Re: Mutually recursive (local) macros
Date: 
Message-ID: <7cy733iy6s.fsf@pbourguignon.anevia.com>
rock69 <···········@gmail.com> writes:

> I ask this just out of sheer curiosity and for no specific (at least
> at the moment) application purpose. I know it's possible to define
> recursive macros globally with DEFMACRO in a straightforward fashion,
> but I also understand that you can't do that locally with MACROLET
> because the latter behaves (just an analogy) like FLET rather than
> LABELS (ref. Paul Graham ANSI CL or the HyperSpec). So you can't
> write, I immagine, things like mutually (local) recursive macros with
> something like MACROLET.


This is not exactly exact.

You have to distinguish macro expansion time from compilation or run
time.

When you have a macro body, some code is executed at macro expansion
time, and the result of the macro body is then optionnaly compiled (at
compilation time) then run at run time.

If during these later times, compilation or run, another macro is
encountered, then macroexpansion time ticks again.


So the question is wether your mutually recursive macros need
themselves at macroexpansion time, or at compilation/run time?

(macrolet ((a (x)
             (b x)   ; macroexpansion time
            `(b ,x)) ; compilation/run time
            
           (b (x)
             (a x)    ; macroexpansion time
            `(a ,x))) ; compilation/run time
  (a 2))


With macrolet, you cannot define mutually recursive macros with a loop
at macroexpansion time, but there is no problem in having them use
themselves recursively, in the expansion, because they will actually
be used at compilation/run time.


Now, thinking about macros _using_ macros, macros normally are used to
define a language.  Having mutually recursively using macros would
mean that you are defining a language A in terms of a language B, it
self defined in terms of the language A.  This wouldn't lead too far
would it?


So,

> I wonder why such a possibility, at least in principle, was not taken
> into account. Perhaps it's not considered useful or, quite possibly,
> it could be very hard or even impossible to achieve. I'm very curious
> as to why this is so in the standard, and if it is at all possible,
> theoretically, to write (with defmacro for instance) an alternative to
> MACROLET that is more like LABELS (again just an analogy of course).

you don't really need it. 


-- 
__Pascal Bourguignon__