[racket] Flatten syntax and runtime phases?

From: Eli Barzilay (eli at barzilay.org)
Date: Fri Jul 13 17:24:53 EDT 2012

Three hours ago, Nick Sivo wrote:
> > Heh -- this is very nice to hear, since Arc is supposed to be
> > using macros in a way that highlights unhygienic macros...
> My take on it is that Arc's original macros were designed to be
> powerful but simple.  All you need to know in order to use them are
> the language primitives and any functions and macros you've defined.

That's the case for any good macro system: the fact that the
meta-level is inside the same language.  It's therefore true for both
Arc macros and Racket macros -- it just happens that the latter is
much more sophisticated so it's not "just sexprs"...  But you can view
it very similarly: it's sexprs with some extensions that make a whole
bunch of stuff useful -- for example, having syntax objects means that
they can hold source location information.  (Whereas some Lisps kind
of hack it in via backchannels like a hash table that maps lists to
source locations.)

> There were only a few places where breaking hygiene was a feature,
> and those weren't really given any special attention.
> In comparison, syntax-case and syntax-parse macros require the user
> to learn much more before using them[1], and they require fancier
> tricks to group arguments into pairs[2],

That's not really required -- you can just use the syntax type as is.
For some examples, see

> or to expose an unhygienic binding.

See syntax parameters for something that fills 99% of the cases that
need that.

> They also don't allow you to use a function you just defined in
> phase 0 as part of the macro processing, something which initially
> threw me for a loop.

Yeah -- Racket-style phase separation is a feature that is independent
of the question of how syntax is represented.  It happens to be a
feature that is really good at organizing your system and avoid known
issues of "flat" single namespace things.

An hour and a half ago, Matthias Felleisen wrote:
> Hygiene -- as it is used nowadays, not the thing for which I
> imported Barendregt's original term -- does not just prohibit
> certain idioms it also enables some that cannot be implemented with
> old macro system.

To clarify what Matthias wrote, this is mainly done by extending the
type that is used to represent syntax.  As I said above, traditional
lisps go with plain sexprs which makes them extremely simple, but they
also lack some of the information that makes more features possible.
(Like hygiene.)

> And yes, the cost you pay is that you need to learn a distinct
> notation. BUT I would argue that for true syntax programmers, this
> is a plus because it reminds them of the very important fact that
> syntax is evaluated at a very different time from run-time code, and
> that values flowing from one phase to another work only by
> 'accident'. [I understand enough to know that it isn't really by
> accident but in a sense it is and often it fails in subtle ways.]

I usually like to point at Fare's blog post about `eval-when' and the
kind of disasters you run into with a single flat namespace for both
code and macros: http://fare.livejournal.com/146698.html

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the users mailing list.