From: Paul Tarvydas
Subject: macrology
Date: 
Message-ID: <flh3ou$pcr$1@aioe.org>
I think that I want to define a pair of macros, where the second macro uses
a gensym created inside the first macro as in this incorrect piece of code:

(setq next 'hello)

(defmacro machine ()
  (let ((next (gensym "next")))
    (macrolet ((go-state (where)
                 `'(setq ,next ',where)))
      `(prog ()
         ,(go-state idle)))))    ;;;;;;;;;;; this line

(defun test ()
  (pprint (macroexpand '(machine))))

The marked line should emit code something like

(setq |gensymvar| 'idle)

but, instead it uses the global (not local) variable "next" and produces

(set hello 'idle)

CL2e appears to say that it is impossible to do what I want.  Is this
correct, or have I missed some obvious trick?

thanx
pt

From: Pascal Bourguignon
Subject: Re: macrology
Date: 
Message-ID: <877iir4zd0.fsf@thalassa.informatimago.com>
Paul Tarvydas <········@visualframeworksinc.com> writes:

> I think that I want to define a pair of macros, where the second macro uses
> a gensym created inside the first macro as in this incorrect piece of code:
>
> (setq next 'hello)
>
> (defmacro machine ()
>   (let ((next (gensym "next")))
>     (macrolet ((go-state (where)
>                  `'(setq ,next ',where)))
>       `(prog ()
>          ,(go-state idle)))))    ;;;;;;;;;;; this line

I see only one macro, therefore you should have no problem.  

Your error is to define the go-state macro at macroexpansion time, and
to use it at run-time. Move the backquote up a tad.
Do not use PROG, unless you've read and understood L.i.S.P.


(defmacro machine ()
  (let ((next (gensym "next")))
    `(macrolet ((go-state (where)
                 `(setq ,,next ',where)))
      (progn
         (go-state idle)))))


Note that if that's all go-state does, it hardly needs to be a macro,
you could s/macrolet/flet.


-- 
__Pascal_Bourguignon__               _  Software patents are endangering
()  ASCII ribbon against html email (o_ the computer industry all around
/\  1962:DO20I=1.100                //\ the world http://lpf.ai.mit.edu/
    2001:my($f)=`fortune`;          V_/   http://petition.eurolinux.org/
From: Pillsy
Subject: Re: macrology
Date: 
Message-ID: <982d6f38-7445-4cfe-b7a1-82c6c30d09a4@c4g2000hsg.googlegroups.com>
On Jan 2, 5:49 pm, Pascal Bourguignon <····@informatimago.com> wrote:
[...]
> Do not use PROG, unless you've read and understood L.i.S.P.

Why not? It seems like it's usually the most convenient thing to use
in those (rare) circumstances when you need to use GO statements.  Of
course, if you just want PROGN, like the OP did, then that's the thing
to use.

Cheers,
Pillsy
From: Barry Margolin
Subject: Re: macrology
Date: 
Message-ID: <barmar-3104C0.20050503012008@comcast.dca.giganews.com>
In article 
<····································@c4g2000hsg.googlegroups.com>,
 Pillsy <·········@gmail.com> wrote:

> On Jan 2, 5:49�pm, Pascal Bourguignon <····@informatimago.com> wrote:
> [...]
> > Do not use PROG, unless you've read and understood L.i.S.P.
> 
> Why not? It seems like it's usually the most convenient thing to use
> in those (rare) circumstances when you need to use GO statements.

Presumably that's one of the things you'll learn from reading and 
understanding L.i.S.P.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Pascal Bourguignon
Subject: Re: macrology
Date: 
Message-ID: <87y7b62tsu.fsf@thalassa.informatimago.com>
Pillsy <·········@gmail.com> writes:

> On Jan 2, 5:49�pm, Pascal Bourguignon <····@informatimago.com> wrote:
> [...]
>> Do not use PROG, unless you've read and understood L.i.S.P.
>
> Why not? It seems like it's usually the most convenient thing to use
> in those (rare) circumstances when you need to use GO statements.  Of
> course, if you just want PROGN, like the OP did, then that's the thing
> to use.

If you just want PROGN, use PROGN.

PROG establishes lexical bindings.  If you give it no binding, and you
want to use GO, then it would be better to use TAGBODY, which is more
explicit. Otherwise use PROGN or LOCALLY, for the same reasons PROGN
or LOCALLY are preferable to (LET () ...).

Note that like TAGBODY, PROG doesn't return the result of the last
expression, contrarily to what you seem to infer. (But perhaps you
just didn't notice that it was PROG and not PROGN).

-- 
__Pascal_Bourguignon__               _  Software patents are endangering
()  ASCII ribbon against html email (o_ the computer industry all around
/\  1962:DO20I=1.100                //\ the world http://lpf.ai.mit.edu/
    2001:my($f)=`fortune`;          V_/   http://petition.eurolinux.org/
From: Pascal Bourguignon
Subject: Re: macrology
Date: 
Message-ID: <87tzlu2taa.fsf@thalassa.informatimago.com>
x
-- 
__Pascal_Bourguignon__               _  Software patents are endangering
()  ASCII ribbon against html email (o_ the computer industry all around
/\  1962:DO20I=1.100                //\ the world http://lpf.ai.mit.edu/
    2001:my($f)=`fortune`;          V_/   http://petition.eurolinux.org/
From: Pascal Bourguignon
Subject: Re: macrology
Date: 
Message-ID: <87k5mq2sys.fsf@thalassa.informatimago.com>
Pillsy <·········@gmail.com> writes:

> On Jan 2, 5:49�pm, Pascal Bourguignon <····@informatimago.com> wrote:
> [...]
>> Do not use PROG, unless you've read and understood L.i.S.P.
>
> Why not? It seems like it's usually the most convenient thing to use
> in those (rare) circumstances when you need to use GO statements.  Of
> course, if you just want PROGN, like the OP did, then that's the thing
> to use.

Sorry, I confused PROG and PROGV.

Still, when there's no GO or no binding, it would be better to use LET
or PROGN rather than PROG (for the same reason we prefer to use WHEN
or UNLESS rather than IF).

-- 
__Pascal_Bourguignon__               _  Software patents are endangering
()  ASCII ribbon against html email (o_ the computer industry all around
/\  1962:DO20I=1.100                //\ the world http://lpf.ai.mit.edu/
    2001:my($f)=`fortune`;          V_/   http://petition.eurolinux.org/
From: John Thingstad
Subject: Re: macrology
Date: 
Message-ID: <op.t4enctkqut4oq5@pandora.alfanett.no>
P� Fri, 04 Jan 2008 04:02:51 +0100, skrev Pascal Bourguignon  
<···@informatimago.com>:

>
> Sorry, I confused PROG and PROGV.
>

which establishes DYNAMIC bindings

> Still, when there's no GO or no binding, it would be better to use LET
> or PROGN rather than PROG (for the same reason we prefer to use WHEN
> or UNLESS rather than IF).
>

see above

--------------
John Thingstad
From: John Thingstad
Subject: Re: macrology
Date: 
Message-ID: <op.t4enkmj4ut4oq5@pandora.alfanett.no>
P� Fri, 04 Jan 2008 13:23:07 +0100, skrev John Thingstad  
<·······@online.no>:

> P� Fri, 04 Jan 2008 04:02:51 +0100, skrev Pascal Bourguignon  
> <···@informatimago.com>:
>
>>
>> Sorry, I confused PROG and PROGV.
>>
>
> which establishes DYNAMIC bindings
>
>> Still, when there's no GO or no binding, it would be better to use LET
>> or PROGN rather than PROG (for the same reason we prefer to use WHEN
>> or UNLESS rather than IF).
>>
>
> see above

I see that can be misunderstood.
PROGV uses dynamic variables while PROG, PROG* uses lexical variables.

--------------
John Thingstad
From: Kent M Pitman
Subject: Re: macrology
Date: 
Message-ID: <u8x35a9z7.fsf@nhplace.com>
"John Thingstad" <·······@online.no> writes:

> > > Sorry, I confused PROG and PROGV.
> >
> > which establishes DYNAMIC bindings
>
> I see that can be misunderstood.
> PROGV uses dynamic variables while PROG, PROG* uses lexical variables.

Heh.  That can still be misunderstood.  (Then again, what text cannot
be, given no control of the receiving processor?)  I was going to add
"so can PROG and PROG*" but that wouldn't help either with more
explication.  So, at some risk of doing just the opposite, let me try
to clarify:

PROGV dynamically uses dynamic variables; that is, it dynamically
makes the choice of what variables to dynamically bind at runtime.
e.g., 

 (let ((a 1) (b 2))
   (declare (special a b))
   (progv (list (elt '(a b) (random 2)))
          (list 3)
     (list a b)))

    => (3 2)
 OR => (1 3)

That is, it dynamically decides (in this case at random, though most
applications wouldn't be so capricious) which variable to bind, so
depending on which variable it binds specially, it yields a different
result.

PROG and PROG* defaultly use lexical variables but can lexically
be asked to use dynamic variables by including a SPECIAL declaration.
e.g.,

 (let ((a 1) (b 2))
   (declare (special a b))
   (flet ((f () (list a b)))
     (prog ((a 3) (b 4))
       (declare (special a))
       (return (f)))))
 => (3 2)

That is, in this case the compiler statically knows that the 
inner A binding will be special and the inner B binding will 
be dynamically.  The binding itself is done dynamically, but
the choice of what binding to do is not dynamic.
From: Vassil Nikolov
Subject: Re: macrology
Date: 
Message-ID: <snwhcht61jd.fsf@luna.vassil.nikolov.names>
"John Thingstad" <·······@online.no> writes:

> ...
> PROGV uses dynamic variables while PROG, PROG* uses lexical variables.

  Well, it would be better to say that PROGV can _only_ bind dynamic
  variables, while PROG etc. can bind both lexical and dynamic
  variables.  The essential difference is that with PROGV, the
  variables themselves can be known as late as run time, while LET,
  LET*, PROG, PROG*, etc. require that the variables are known no
  later than compile time.

  (The latter case is by far the most frequently occurring one, which
  is why PROGV comes into play very rarely.)

  ---Vassil.


-- 
Bound variables, free programmers.