public inbox for cgen@sourceware.org
 help / color / mirror / Atom feed
* Opinions wanted: What should (.list pmacro-name 42) do?
@ 2009-08-20 17:30 Doug Evans
  2009-08-20 17:44 ` Doug Evans
  2009-08-20 18:24 ` Jim Blandy
  0 siblings, 2 replies; 4+ messages in thread
From: Doug Evans @ 2009-08-20 17:30 UTC (permalink / raw)
  To: cgen

Hi.

What should the output of

(define-pmacro (foo a) (add a 1))
(.list foo 42)

be?

Currently the result is (<pmacro> 42)
where <pmacro> is the pmacro object for "foo".

It's not ideal because it means that a pmacro object "escapes" 
pmacro-processing and can be seen by, for example, rtl compilation.

However, it's not that unexpected.  The user asked for a list containing 
two objects, the pmacro and 42.
This is akin to saying (list + 42) in Scheme.

We *could* have the pmacro evaluator re-examine the result and if it 
sees (<pmacro> mumble) then re-expand it.  That's what we do for symbols 
today (i.e. if the result of pmacro-expansion is a symbol that names a 
pmacro, we re-evaluate it), but that has problems, e.g.
http://sourceware.org/ml/cgen/2009-q3/msg00052.html
and I'm leaning toward removing that behavior.

It's not clear to me what The Right Thing to do is.
Opinions?

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Opinions wanted: What should (.list pmacro-name 42) do?
  2009-08-20 17:30 Opinions wanted: What should (.list pmacro-name 42) do? Doug Evans
@ 2009-08-20 17:44 ` Doug Evans
  2009-08-20 18:24 ` Jim Blandy
  1 sibling, 0 replies; 4+ messages in thread
From: Doug Evans @ 2009-08-20 17:44 UTC (permalink / raw)
  To: cgen

Doug Evans wrote:
> Hi.
>
> What should the output of
>
> (define-pmacro (foo a) (add a 1))
> (.list foo 42)
>
> be?
>
> Currently the result is (<pmacro> 42)
> where <pmacro> is the pmacro object for "foo".
>
> It's not ideal because it means that a pmacro object "escapes" 
> pmacro-processing and can be seen by, for example, rtl compilation.
>
> However, it's not that unexpected.  The user asked for a list 
> containing two objects, the pmacro and 42.
> This is akin to saying (list + 42) in Scheme.
>
> We *could* have the pmacro evaluator re-examine the result and if it 
> sees (<pmacro> mumble) then re-expand it.  That's what we do for 
> symbols today (i.e. if the result of pmacro-expansion is a symbol that 
> names a pmacro, we re-evaluate it), but that has problems, e.g.
> http://sourceware.org/ml/cgen/2009-q3/msg00052.html
> and I'm leaning toward removing that behavior.
>
> It's not clear to me what The Right Thing to do is.
> Opinions?
>

[For completeness' sake ...]
An alternative is of course to flag any pmacros that "escape" as 
errors.  We need to do that anyway for cases like (.list 42 foo).

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Opinions wanted: What should (.list pmacro-name 42) do?
  2009-08-20 17:30 Opinions wanted: What should (.list pmacro-name 42) do? Doug Evans
  2009-08-20 17:44 ` Doug Evans
@ 2009-08-20 18:24 ` Jim Blandy
  2009-08-21  4:30   ` Doug Evans
  1 sibling, 1 reply; 4+ messages in thread
From: Jim Blandy @ 2009-08-20 18:24 UTC (permalink / raw)
  To: Doug Evans; +Cc: cgen

On Thu, Aug 20, 2009 at 10:30 AM, Doug Evans<dje@sebabeach.org> wrote:
> Hi.
>
> What should the output of
>
> (define-pmacro (foo a) (add a 1))
> (.list foo 42)
>
> be?
>
> Currently the result is (<pmacro> 42)
> where <pmacro> is the pmacro object for "foo".
>
> It's not ideal because it means that a pmacro object "escapes"
> pmacro-processing and can be seen by, for example, rtl compilation.
>
> However, it's not that unexpected.  The user asked for a list containing two
> objects, the pmacro and 42.
> This is akin to saying (list + 42) in Scheme.
>
> We *could* have the pmacro evaluator re-examine the result and if it sees
> (<pmacro> mumble) then re-expand it.  That's what we do for symbols today
> (i.e. if the result of pmacro-expansion is a symbol that names a pmacro, we
> re-evaluate it), but that has problems, e.g.
> http://sourceware.org/ml/cgen/2009-q3/msg00052.html
> and I'm leaning toward removing that behavior.

Macros should definitely be able to expand to calls to other macros
somehow; doesn't (.list 'foo 42) do this?  If it does, then I don't
see much point in allowing (.list foo 42) to do so as well.  The
source world and the value world need to interact only in
easy-to-reason-about ways, or you end up with stuff like m4, which is
just chaos.

This reminds me of the "3-d macro" problem in Scheme, where macros can
place values that can't actually be written in Scheme source code
(procedure objects, say) into the tree that the compiler eventually
sees.  I've always thought the cleanest thing was to reject such code,
as it didn't seem useful, and made a weird breach between macro
expansion time and run time.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Opinions wanted: What should (.list pmacro-name 42) do?
  2009-08-20 18:24 ` Jim Blandy
@ 2009-08-21  4:30   ` Doug Evans
  0 siblings, 0 replies; 4+ messages in thread
From: Doug Evans @ 2009-08-21  4:30 UTC (permalink / raw)
  To: Jim Blandy; +Cc: cgen

Jim Blandy wrote:
> On Thu, Aug 20, 2009 at 10:30 AM, Doug Evans<dje@sebabeach.org> wrote:
>   
>> Hi.
>>
>> What should the output of
>>
>> (define-pmacro (foo a) (add a 1))
>> (.list foo 42)
>>
>> be?
>>
>> Currently the result is (<pmacro> 42)
>> where <pmacro> is the pmacro object for "foo".
>>
>> It's not ideal because it means that a pmacro object "escapes"
>> pmacro-processing and can be seen by, for example, rtl compilation.
>>
>> However, it's not that unexpected.  The user asked for a list containing two
>> objects, the pmacro and 42.
>> This is akin to saying (list + 42) in Scheme.
>>
>> We *could* have the pmacro evaluator re-examine the result and if it sees
>> (<pmacro> mumble) then re-expand it.  That's what we do for symbols today
>> (i.e. if the result of pmacro-expansion is a symbol that names a pmacro, we
>> re-evaluate it), but that has problems, e.g.
>> http://sourceware.org/ml/cgen/2009-q3/msg00052.html
>> and I'm leaning toward removing that behavior.
>>     
>
> Macros should definitely be able to expand to calls to other macros
> somehow; doesn't (.list 'foo 42) do this?

Hey Jim!  Thanks for the feedback.

I'm not quite sure what you mean, alas.  [Apologies.  I can guess, but ...]

CGEN's pmacro system doesn't (currently) have quoting a la ' (or quote), 
btw.
[The Scheme reader will accept it of course, but the pmacro system won't 
(currently) do anything sensible with (quote foo).]

> If it does, then I don't
> see much point in allowing (.list foo 42) to do so as well.  The
> source world and the value world need to interact only in
> easy-to-reason-about ways, or you end up with stuff like m4, which is
> just chaos.
>
> This reminds me of the "3-d macro" problem in Scheme, where macros can
> place values that can't actually be written in Scheme source code
> (procedure objects, say) into the tree that the compiler eventually
> sees.  I've always thought the cleanest thing was to reject such code,
> as it didn't seem useful, and made a weird breach between macro
> expansion time and run time.
>   

Note that one can pass pmacros as parameters to other pmacros and invoke 
them.  But the user is required to explicitly do this, CGEN won't 
(currently) take the result of a macro and rescan it for further pmacro 
invocations (except, currently, in the case where the result of the 
pmacro expansion is a single symbol).

In Scheme the result of (list + 1 2) is (<primitive-procedure-plus> 1 
2), not 3.

For reference sake, in Scheme,
(define-macro (foo a) `(bar ,a))
(define-macro (bar a) `(baz ,a))
(foo 3) ;; expands to (bar 3) which in turn expands to (baz 3)

In CGEN that would be
(define-pmacro (foo a) (bar a))
(define-pmacro (bar a) (baz a))

Using pmacro-trace in Guile I get:

guile> (pmacro-trace '(foo 3) (unspecified-location))
Pmacro expanding: (foo 3)
Pmacro location: standard input:10:16
    Expanding: (foo 3)
          env: ()
     location: standard input:10:16
    Expanding: (bar a)
          env: ((a . 3))
     location: standard input:3:26
       result: (baz 3)
       result: (baz 3)
Pmacro result: (baz 3)
(baz 3)

And in Scheme,
(define-macro (foo a) `(list bar ,a))
(define-macro (bar a) `(baz ,a))
(foo 3) ;; ==> (#<macro! bar> 3) ;; Note that Scheme didn't re-expand 
the result and turn it into (baz 3).

In CGEN,
(define-pmacro (foo a) (.list bar a))
(define-pmacro (bar a) (baz a))
(foo 3) ;; ==> (<pmacro bar> 3)

We don't have to follow Scheme per se, but I'm worried that being 
excessively clever here will lead to issues (like in  
http://sourceware.org/ml/cgen/2009-q3/msg00052.html).
One issue is: what if the user *wants* (.list foo 42) to be (<pmacro 
foo> 42).  S/he can always explicitly re-expand the expression to turn 
it into (add 42 1), e.g., with (.eval (.list foo 42)), but there's no 
(current) way to prevent the re-expansion if it was done automagically 
(unless, for example, we add a quoting system, which I hesitate to do in 
part because it's yet another complication to the language).

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-08-21  4:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-20 17:30 Opinions wanted: What should (.list pmacro-name 42) do? Doug Evans
2009-08-20 17:44 ` Doug Evans
2009-08-20 18:24 ` Jim Blandy
2009-08-21  4:30   ` Doug Evans

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).