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

Re: Crash course on macros?



The best way to get into macros is to fold your copy of the DRM open at
the relevent section and go through some real-world examples. If you
don't have the Gwydion Dylan sources to hand, you can get a good
selection of macros from:

http://www.ccc.de/cgi-bin/cvsweb/gd/src/d2c/runtime/dylan/macros.dylan?rev=1.7

This starts nice and simple with:

define macro begin
    { begin ?:body end } => { ?body };
end;

Which translates:

begin
    #f;
end;

into just

    #f;

The only really confusing thing to macros (apart from #key and #rest
macro parameters...) is the ?:body syntax. There *should* be a name
before :body, ie:

define macro begin
    { begin ?theBody:body end } => { ?theBody };
end;

However, as a convenience, if a macro rule has only one parameter of
that type, you can skip the name and refer to it directly. If we had two
bodies (in a naive if/else implementation, for example), they'd need to
be given names, and referred to using them.

?:variables and ?variables are therefore a reference to the only set of
variables matched by the macro rule. ?:variables will allow only
variable, not expressions or non-variable,  language constructs to
match. ?variables* I don't know about. :-(

Taking a more complex example, the if macro is slightly nested, having
auxilliary rules:

define macro if
    { if (?x:expression) ?:body ?elses end }
      => make-if({ ?x }, { ?body }, { ?elses })
  elses:
    { else ?:body } => { ?body }
    { elseif (?x:expression) ?:body ... }
      => make-if({ ?x }, { ?body }, { ... })
    { } => { #f };
end;

The ?elses ties in to the elses: auxilliary rule. Auxilliary rules are
sub-macros, they look like out-of-sequence nested case statements, which
may be a good way of regarding them. The ... in some of the elses:
clauses makes them iterate over the content matched by the ?elses,
breaking it down into chunks the auxilliary macros can handle. As with
any loop, you need to know how to end, that's what this line is for:

{ } => { #f };

It matches nothing, so when nothing is left of the ?elses, it matches
and the elses: end.
The make-if() call in the main rule and the second auxilliary rule is a
call to another macro.

Can you give examples of macros using the constructs that are
problematic so people can take a look and go through them?

- Rob.


Nolan Darilek wrote:

> I don't understand macros, however. I understand the different types,
> and what they are intended to do in principle, but I don't understand
> the syntax within the body. Specifically, the ?variables, the
> ?:variables, the ?:variables*, etc. :) I can guess at a few of the
> constructs since I have a passing familiarity with regexps, but I'm
> still clueless, even after studying the DRM and its examples.

--
Rob Myers  -  robm@tdv.com         The Digital Village  -  www.tdv.com
MacOS wonderfulness for The Hitch Hiker's Guide to the Galaxy Game.
"Arthur bought the Apple anyway."-So Long & Thanks For All The Fish.




Follow-Ups: References: