From: Jeff
Subject: Generating recursive macros
Date: 
Message-ID: <1vxTc.153536$eM2.148253@attbi_s51>
Wondering if someone could lend a quick hand with this one. I can't
seem to get the correct code for the following concept:

(defmacro foo ()
  (let ((f (gensym)))
    `(labels ((,f () (,f)))))

Of course, this isn't the macro I want, but the concept is there. I'd
like to use a generated symbol for a label name so that I could call it
recursively from within the label.

I'm sure I'm just missing something simple. Help appreciated. Thanks!

Jeff

From: Rainer Joswig
Subject: Re: Generating recursive macros
Date: 
Message-ID: <joswig-D363E3.01552515082004@news-50.dca.giganews.com>
In article <·······················@attbi_s51>,
 "Jeff" <···@nospam.insightbb.com> wrote:

> Wondering if someone could lend a quick hand with this one. I can't
> seem to get the correct code for the following concept:

what concept?

> (defmacro foo ()
>   (let ((f (gensym)))
>     `(labels ((,f () (,f)))))
> 
> Of course, this isn't the macro I want, but the concept is there. I'd
> like to use a generated symbol for a label name so that I could call it
> recursively from within the label.
> 
> I'm sure I'm just missing something simple. Help appreciated. Thanks!
> 
> Jeff

+1 parentheses:

(defmacro foo ()
  (let ((f (gensym)))
    `(labels ((,f () (,f))))))

Well, it will not do much if you call (foo).

The following will be a loop...

(defmacro foo ()
  (let ((f (gensym)))
    `(labels ((,f () (,f)))
       (,f))))
From: Jeff
Subject: Re: Generating recursive macros
Date: 
Message-ID: <bUxTc.291592$JR4.201845@attbi_s54>
Rainer Joswig wrote:

> In article <·······················@attbi_s51>,
>  "Jeff" <···@nospam.insightbb.com> wrote:
> 
> > Wondering if someone could lend a quick hand with this one. I can't
> > seem to get the correct code for the following concept:
> 
> what concept?
> 
> > (defmacro foo ()
> >   (let ((f (gensym)))
> >     `(labels ((,f () (,f)))))
> > 
> > Of course, this isn't the macro I want, but the concept is there.
> > I'd like to use a generated symbol for a label name so that I could
> > call it recursively from within the label.
> > 
> > I'm sure I'm just missing something simple. Help appreciated.
> > Thanks!
> > 
> > Jeff
> 
> +1 parentheses:
> 
> (defmacro foo ()
>   (let ((f (gensym)))
>     `(labels ((,f () (,f))))))
> 
> Well, it will not do much if you call (foo).
> 
> The following will be a loop...
> 
> (defmacro foo ()
>   (let ((f (gensym)))
>     `(labels ((,f () (,f)))
>        (,f))))

Hmm... there must be a little something wrong in my macro. I should
have tested some more. I was getting the impression that a (gensym)
couldn't be used in that way. Glad I was wrong :)

Jeff
From: Jeff
Subject: Re: Generating recursive macros
Date: 
Message-ID: <P5yTc.11378$TI1.9917@attbi_s52>
Jeff wrote:

> Rainer Joswig wrote:
> 
> > In article <·······················@attbi_s51>,
> >  "Jeff" <···@nospam.insightbb.com> wrote:
> > 
> > > Wondering if someone could lend a quick hand with this one. I
> > > can't seem to get the correct code for the following concept:
> > 
> > what concept?
> > 
> > > (defmacro foo ()
> > >   (let ((f (gensym)))
> > >     `(labels ((,f () (,f)))))
> > > 
> > > Of course, this isn't the macro I want, but the concept is there.
> > > I'd like to use a generated symbol for a label name so that I
> > > could call it recursively from within the label.
> > > 
> > > I'm sure I'm just missing something simple. Help appreciated.
> > > Thanks!
> > > 
> > > Jeff
> > 
> > +1 parentheses:
> > 
> > (defmacro foo ()
> >   (let ((f (gensym)))
> >     `(labels ((,f () (,f))))))
> > 
> > Well, it will not do much if you call (foo).
> > 
> > The following will be a loop...
> > 
> > (defmacro foo ()
> >   (let ((f (gensym)))
> >     `(labels ((,f () (,f)))
> >        (,f))))
> 
> Hmm... there must be a little something wrong in my macro. I should
> have tested some more. I was getting the impression that a (gensym)
> couldn't be used in that way. Glad I was wrong :)
> 
> Jeff

Ahh.. found it! Had to do with some gensym's being local in a cond
statement. Here is an example of what is generated:

(cond
  ((multiple-value-bind (m n) (...) m)
   ; Do stuff with m and n here
  )
  ; more combinations of the same thing
  )

So, of course, the section 'do stuff with m and n' will die because
they are out of scope. However, m and n are gensym'd before the cond
statement. Is there any way to force multiple-value-bind to use a
higher level symbol rather than creating new ones? Or perhaps get the
values of m and n withough using multiple-value-bind?

Thanks again for the replies, everyone.

Jeff
From: Matthew Danish
Subject: Re: Generating recursive macros
Date: 
Message-ID: <20040815003012.GR15746@mapcar.org>
See MULTIPLE-VALUE-SETQ.

-- 
;;;; Matthew Danish -- user: mrd domain: cmu.edu
;;;; OpenPGP public key: C24B6010 on keyring.debian.org
From: Jeff
Subject: Re: Generating recursive macros
Date: 
Message-ID: <XXyTc.11872$TI1.1458@attbi_s52>
Matthew Danish wrote:

> See MULTIPLE-VALUE-SETQ.

Danke. Worked like a charm ;)
From: Pascal Bourguignon
Subject: Re: Generating recursive macros
Date: 
Message-ID: <87oeldb6p6.fsf@thalassa.informatimago.com>
"Jeff" <···@nospam.insightbb.com> writes:

> Wondering if someone could lend a quick hand with this one. I can't
> seem to get the correct code for the following concept:
> 
> (defmacro foo ()
>   (let ((f (gensym)))
>     `(labels ((,f () (,f)))))
> 
> Of course, this isn't the macro I want, but the concept is there. I'd
> like to use a generated symbol for a label name so that I could call it
> recursively from within the label.
> 
> I'm sure I'm just missing something simple. Help appreciated. Thanks!

I don't see where the problem lies:

(defmacro foo ()
  (let ((f (gensym)))
    `(labels ((,f (x) (if (< 1 x) (* x (,f (1- x))) 1)))
       (,f 10))))

(foo) ==> 3628800

But don't feed back read with the (gensym) symbols, they're not interned!

(macroexpand-1 '(foo))
==> (LABELS ((#:G1351 (X) (IF (< 1 X) (* X (#:G1351 (1- X))) 1)))
                              (#:G1351 10)), T

(LABELS ((#:G1351 (X) (IF (< 1 X) (* X (#:G1351 (1- X))) 1))) (#:G1351 10))
==> EVAL: undefined function #:G1351
    [Condition of type SYSTEM::SIMPLE-UNDEFINED-FUNCTION]

(LABELS ((#1=#:G1351 (X) (IF (< 1 X) (* X (#1# (1- X))) 1))) (#1# 10))
==> 3628800

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

Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we.