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

Re: [Scheme-reports] [wg2] in support of single-arity procedural syntax transformers

An hour and a half ago, Alex Shinn wrote:
> On Fri, May 13, 2011 at 10:35 AM, Eli Barzilay <eli@x> wrote:
> > 25 minutes ago, Alex Shinn wrote:
> >>
> >> If you want to insist on exposing the transformer signature, then
> >> you're arguing that none of the other macro systems are worth
> >> supporting,
> >
> > Wrong, same post.
> OK, that post doesn't actually explain what you mean, but we talked
> this out on IRC and I see know what you're suggesting (correct me if
> I'm wrong).
> You suggest that an alternate macro system should support _both_
> their own macros and syntax-object macros natively, that their own
> macros should be tagged somehow, and then the macro expander should
> dispatch on the two types of macros.
> So, for example, er-macro-transformer would return an object like:
>   (list 'I-am-an-ER-macro-transformer #<procedure>)
> and the expander would then do something like
>   (define (expand-macro op expr use-env mac-env)

[Since this is a loaded question, please avoid the implicit bias in
the arguments to that fictitious `expand-macro'.]

>     (cond ((er-macro-transformer? op)
>               ((er-macro-procedure op) expr use-env mac-env))
>              (else
>               (op expr))))

Close.  That would be the case if a syntax case macro system was
required, and I'm avoiding expressing an opinion on that.  (My opinion
is obvious -- as Andre said, not doing so is questionable -- but in
any case it's a different discussion.)

It's possible to have a world where both systems are optional: either
you implement neither (so `syntax-rules' is implemented in some
completely different way, or not at all), one, both, or more.  Either
way it goes, you make the signature for the RHS of a `define-syntax'
the natural `Syntax -> Syntax' *or* a tagged ER or whatever
transformer.  This way, the expander of a system that has only syntax
case will throw an error when encountering a value that is not a
single arity function, and a system with more variants would dispatch
on the tagged kind or on a single input function, or throw an error.
I can imagine something like the system that you referred to (the
extension of ER) as something that would be implemented as:

  (define (expand-macro op sexpr use-env mac-env foo bar)
    (cond [(sc-macro-transformer? op)
           ((sc-macro-procedure op) sexpr use-env)]
          [(rsc-macro-transformer? op)
           ((sc-macro-procedure op) sexpr mac-env)]
          [(er-macro-transformer? op)
           ((er-macro-procedure op) sexpr
                                    (make-rename use-env mac-env)
                                    (make-compare use-env mac-env))]
          [(extended-er-macro-transformer? op)
           ((extended-er-macro-procedure op) sexpr use-env mac-env foo bar)]
          ;; [*]
          [(and (procedure? op) (procedure-arity-includes? op 1))
           (op (...use available information to create some syntax value
                that can be used by a syntax case transformer, assuming
                that it's somehow possible...))]
          [else (error "bad macro value")]))

(Note that the details of sc/rsc/er are just examples, the details are
not relevant.)

> Now, for the plain procedure to be useful expr would actually have
> to be wrapped somehow, and a basic API for structuring and
> destructuring syntax objects would need to be provided, such as what
> R6RS provide (without syntax-case).

[That's assuming that you want both implemented, which I'll continue
to avoid talking about.]

> Yes, technically this would allow ER macros to exist alongside bare
> single-arity lambda expanders.  However, it's a truly hideous hack,

I don't see where's the hideous hack.  On quick browsing, I've seen
code that is supposed to be ER macro code with only two inputs and
code with three, I've also seen SC macros with two and with three
inputs, and to make things fun you've mentioned the possibility of
four or five.  In all of these, the function signature is changed to
make the system do different things, so wrappers are natural rather
than hideous hacks.

> and defeats the whole purpose of an alternate macro system.  It's
> saying "yes, you can have another macro system, but you have to
> implement the syntax-object system first in the core and hack your
> way around that."

I don't see how it's saying that.  Just take the above example, and
comment out the [*] branch, and you don't need to do all of that.
(Obviously, in such a system (syntax-rules ...) would evaluate to one
of the tagged values.)

[But of course, if you want to specify some actual procedural common
macro layer, then you need to choose *something*.  Either specify a
system based on syntax objects, or specify the arguments that are
passed along the sexpr.  IMO, the former is better -- one point is
that it's easier to extend (add more information to syntax objects),
and perhaps a better point is that I know how ER macros could be built
on top of them but I've never seen a syntax case system built on top
of ER macros -- and, IMO, a standard should shoot for the more
powerful system that is used in practice, so, IMO, to choose ER macros
you need to show how to do just that.  But the number of "IMO"s in
that is exactly why I really don't want to talk about that.]

> Just like if you have a syntax-case system, you don't want to
> clutter up the core with ER macros and load them as a library, [...]

At least for this direction, I can see how to easily do that easily --
the `er-macro-transformer' would simply create a syntax to syntax

40 minutes ago, Alaric Snell-Pym wrote:
> Ugly hack for sure. Looks like the *core* would need to know about
> all the macro systems in use.

Modularizing the above code is simple, see SICP.

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

Scheme-reports mailing list