From: Kirt Undercoffer
Subject: Re: Dynamic variable creation in Lisp
Date: 
Message-ID: <33E9BAA0.1177@worldnet.att.net>
Hi!

I appreciate everyone's responses on this question.  Currently because
of the following twist and because I can't find an explicit
justification
for the use of variables described in my previous post I am in fact
using
the generated data structures directly.

The twist is this:  when I invoke the following macro from the toploop
it works correctly.  However when the program invokes the macro it
always
generates the same symbol name!!! Even though I'm not using this
anymore,
I'd appreciate comments.  I had thought that perhaps a variable capture
thing was occuring but the macro doesn't have to evaluate the generated
symbol
more than once and the macro itself is invoked at only two points in the
program
(in fact using the current data set, there is only one execution path so
the
macro is called at time t0 and then at time t1, etc. and always
generates the
very first symbol name generated on the first invokation.  I can't see
that I
have any hidden situation where I have accidentally created a constant. 
Everything
appears correct using macroexpand.  Any ideas?

(defmacro generate-concept (concept-type referent referent-type)
   (let ((*temp* (gentemp "CONCEPT-")))
   `(progn
     (setf ,*temp*
     (make-instance 'concept
                    :concept-type ,concept-type 
                    :context nil
                    :ref (make-instance 'referent :type
,referent-type)))
     ',*temp*)))


Originally I had a defconcept function rather than doing the
make-instance thing
(defconcept provides some checking since the concept-type has to be
predefined).

Thanks!

Kirt Undercoffer

From: Kirt Undercoffer
Subject: Re: Dynamic variable creation in Lisp
Date: 
Message-ID: <33EBAE1F.3A@worldnet.att.net>
Thanks!!  Once understood, the problem is obvious.  The should
have thought this out more. The bottom line is that I was in fact
generating constants exactly what the FAQ says to look for!  

Vassili Bykov wrote:

> In article <·············@worldnet.att.net>,
>   Kirt Undercoffer <·····@worldnet.att.net> wrote:
> > [...]  when I invoke the following macro from the toploop
> > it works correctly.  However when the program invokes the macro it
> > always
> > generates the same symbol name!!!
>   [...]

> You should realize that what you see in DEFMACRO is, in a certain sense,
> evaluated twice.
> 
> Firstly (often at compilation time), forms of the expansion function are
> evaluated and the result is spliced into the program in place of the macro
> call.  Secondly, at run time, this result form is evaluated.
> 
> If you look carefully at your macro, you will realize that LET and GENTEMP
> are evaluated when the macro is expanded, which is too early for what you
> want.  
...
> and, quite naturally, it keeps setting the value of same symbol.  It
> works from the toplevel because there the form is read and expanded
> each type you type it in so the defect is hidden.
> 
> To get the effect you want, LET and GENTEMP should be in the *expansion*,
> not the expander, of GENERATE-CONCEPT.
>
From: Kirt Undercoffer
Subject: Re: Dynamic variable creation in Lisp
Date: 
Message-ID: <33EBAED0.3759@worldnet.att.net>
Thanks very much!  This should have occurred to me.

Barry Margolin wrote:

> 
> In article <·············@worldnet.att.net>,
> Kirt Undercoffer  <·····@worldnet.att.net> wrote:
> ]The twist is this:  when I invoke the following macro from the toploop
> ]it works correctly.  However when the program invokes the macro it
> ]always
> ]generates the same symbol name!!!

> GENTEMP is used outside the expansion code.  So it's only called at compile
> time, when the compiler is expanding the macro, rather than at runtime when
> the generated code is being run.  This means that it will only be called
> once for each invocation of the macro within a file being compiled.  The
> generated code will then have the symbol that it created saved in the
> expansion.