guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: macros, procedure->macro


From: Dirk Herrmann
Subject: Re: macros, procedure->macro
Date: Wed, 17 Jul 2002 00:00:09 +0200 (CEST)

On 15 Jul 2002, Neil Jerram wrote:

> >>>>> "Dirk" == Dirk Herrmann <address@hidden> writes:
> 
>     Dirk> Macro expansion is neither performed like reading, nor like 
> evaluation.
>     Dirk> Macro expansion is blocked by quoting _and_ macro definitions.  It 
> is not
>     Dirk> blocked by lambda or other special forms.  Since macro expansion is
>     Dirk> blocked by macro definitions, recursive macro definitions are 
> possible.
> 
> This sounds good.  But, given that the code for a macro definition
> gets wrapped in a lambda, perhaps it would be simpler to say that all
> lambdas block macroexpansion, and that macroexpansion of the code
> inside the lambda happens when the lambda is first used.  This seems
> well defined and easy to understand to me.

Well, I have to correct myself (actually, Marius has already done so):  I
confused define-macro and its mechanisms with define-syntax. Certainly,
the following will not work:

>     Dirk>   (define (foo) (bar))
>     Dirk>   (define-macro (bar) #f)
>     Dirk>   (foo)

And _neither_ will

>     Dirk>   (define-macro (foo x) `(list ,(bar x) ,x))
>     Dirk>   (define-macro (bar x) `(* ,x ,x))

Sorry for the confusion (oh boy).  However, the following will work
(hopefully I am getting it right this time...):

      (use-syntax (ice-9 syncase))
      (define-syntax foo (syntax-rules () ((foo) (bar))))
      (define-syntax bar (syntax-rules () ((bar) (write "bar"))))
      (foo)

and here applys what I wanted to express, namely that the use of bar in
the line where foo is defined is not expanded at that moment.

> If we follow the all lambdas idea, then the `define' example would
> work as well.  Is there any reason why this would be a _bad_ thing?

First, it is confusing.  In the _current_ system, the following works,
since currently lambda blocks macro expansion:
   (define-macro (foo x) `(list ,(bar x) ,x))
   (define-macro (bar x) `(* ,x ,x))
   (foo)
Thus, we can define the following:
   (define-macro (foo) `'first)
   (define (bar) (foo))
   (define (yuck expand?) (if expand? (bar) #f))
   (yuck <some-input-data>)
   (define-macro (foo) `'second)
   (yuck #t) 
Now, what does the last expression deliver?  It depends on what the value
of <some-input-data> was.  This is not what I expect from a macro system.

Second, you can't optimize the execution phase by writing out expanded
code and read it in later:  Only code that has been executed once is
expanded.  How could you write out the expanded version of bar in the
above example? You can't since it depends on your value of
<some-input-data> what bar becomes.  Thus, you also can not provide a
pre-compiled version of bar.  A lot of compiler optimization techniques
are impossible to use, like function inlining etc.

Third, it complicates the execution phase, since you always have to be
aware of still unexpanded functions in the executor.

>     Dirk> However, it may be that different macro implementations with 
> different
>     Dirk> behaviours can co-exist.  For example, I don't see why you 
> shouldn't be
>     Dirk> able to mix calls to procedure->memoizing-macro with calls to
>     Dirk> define-macro.  Then, for each of the different macro systems the 
> behaviour
>     Dirk> would have to be defined separately.  Not all possible systems will 
> comply
>     Dirk> with the demand for a system that supports compilation and efficient
>     Dirk> execution, though.
> 
> In general, yes.  I don't understand your specific example, though, as
> define-macro is implemented using procedure->memoizing-macro, so they
> are the same implementation.

Well, in that paragraph above replace 'define-macro' with 'define-syntax'
and I hope things become clearer.

Best regards,
Dirk Herrmann




reply via email to

[Prev in Thread] Current Thread [Next in Thread]