local-macro-defining macros (was Re: Better Dylan syntax?) 
Author Message
 local-macro-defining macros (was Re: Better Dylan syntax?)

Paul Wilson writes:
> [...]

> >BTW, can dylan macros introduce macros, and change the grammar
> >locally, like Scheme macros?  (If not, I'd say Dylan macros
> >are broken.)  [...]

> [...]

> I think this is an interesting question, because Scheme macros
> can be used to encode semantic information fairly straightforwardly
> in many cases, so that semantic errors (e.g., using a break outside
> a breakable construct) become trivial syntax errors.  In effect,
> Scheme has a scoped, context-sensitive transformational grammar.

> I'm wondering if anyone has accomplished this for a language
> with "normal" (algolesque) syntax.  We're doing on that, and
> if Dylan people haven't already done it, it might be a useful
> generalization of Dylan.

> [...]

Dylan doesn't provide a construct for defining local macros. We needed
something for the infix syntax complete enough to cater for most
needs, and we got that, but local macros weren't a requirement at the
time. It's an interesting problem, though, so I'd like to hear about
your approach.

At heart, the way macros are handled in Dylan has a lot in common with
Lisp. A surface parse is first done to read in a complete form, then
compilation descends that form. To locate a complete form in Lisp, you
just need to match parentheses. The same is true in Dylan, except that
the set of parentheses is extended to include, effectively, macro
names (as open parens) and "end" (as the corresponding close paren).

This approach does have some limitations, and some hair in the
details, but is basically pretty simple. From an implementation point
of view, no deep analysis of the macro definition is necessary in
order to parse a call, just how a call starts (it's name) and
ends. Similarly, little or nothing in the way of annotation is
required from macro authors in order to direct the parser.

Just to elaborate a little on the added requirements of infix over
prefix when it comes to local macros, taking your example, naively I'd
like to be able to write a loop/break macro something like this:

  define macro loop
    { loop ?:body end }
      => { block (exit)
             local macro ?=break // ?= escapes hygiene, making break visible
               { ?=break () end } => { exit() }
             end macro;
             while (#t) ?body end;
           end; }
  end macro;

in pretty much the same way as I might in Lisp or Scheme. I've given
the local macro odd syntax here, "break () end". This is just to
illustrate the point that, in general, a compiler would need to know,
either by working it out for itself or by being told, the syntax of
any local macros that will be put in scope around the input ?body by
the right hand side. It needs to know this before the fact, during
parsing the macro call, otherwise:

    // some stuff...
    break () end;
    // more stuff...

might get interpreted as:

    // some stuff...
    break ()

where "break ()" is parsed as a function call and break's "end"
prematurely ends the loop macro form. There are also oddball cases to
consider like an attempt to substitute an argument code fragment more
than once in the scope of differently-shaped local macros, which would
have to be spotted as an error.

Annotating the left hand side of the macro, it's grammar, to indicate
where local macros will be bound isn't so bad if you look at local
macros as an extension of the input syntax of the binding macro. Then
at the expense of an increase in complexity in the macro system itself
and its implementation, you could indeed move to an algorithm where
macro expansion is integrated with parsing so that context can be
switched as macro call heads are encountered under the control of the
expander function.

It's a bit harder to accept the extra annotation if the local macro is
indirectly bound via a call to another macro in the expansion, but the
right hand sides would be difficult to analyse automatically, or even
find in the case of procedural macros. I guess you could begin to
parse the expansion without fully resolving the macro's arguments and
then use the context known at the point at which the arguments are
actually used, but that might fail if substitution order isn't the
same as input order.

On the other hand, if simplicity and utility rather than completeness
were the most important goals, a worse-is-better style of local macro
support for Dylan could restrict them to have function call or
variable reference (symbol-macro) syntax only so that calls could
always be read without context-sensitive parsing.

-- Keith

Thu, 24 Feb 2000 03:00:00 GMT  
 [ 1 post ] 

 Relevant Pages 

1. Macros defining macros with define-syntax

2. define-macro -> define-syntax

3. define-macro vs define-syntax

4. Local macro within a macro?

5. Question about a macro-defining macro

6. Macro-Defining Macros

7. help sought for macro defining macro

8. Load-time problem with a macro that defines a macro

9. Can macros define anonymous locals?

10. syntax-rules macros with sub-macros

11. defmacro/define-macro using syntax-case

12. A macro involving two sub-macros - where the 2nd macro needs results from the first


Powered by phpBB® Forum Software