Re: How many arguments to a macro transformer? Keith Wright 26 Jul 2005 03:13 UTC

> From: Andre van Tonder <xxxxxx@now.het.brown.edu>
>
> On Sat, 23 Jul 2005, Keith Wright wrote:
>
> > Oops!  I said:
> >
> >> On the other hand, it seems more consistant if
> >>
> >>  (define-syntax (swap! a b) <body)
> >>
> >> were the same as
> >>
> >>  (define-syntax swap! (lambda ( _ a b) <body> ))
> >>
> >> which implies that swap! is right and the rest of
> >> the program is wrong.
> >
> > I just noticed that this is a change you made in
> > the last revision,
>
> Yes, I indeed made the change

Sorry.  As I said, I was playing with it, not just
downloading and running.  I got the versions mixed
and it broke, of course.  I stayed up half the night
debugging, and when I figured out where it was going
wrong, I was so proud that I forgot the rule
"Never post a message after midnight".
It's working now.

Oh well, sometimes somebody who doesn't know what he
is talking about can get the discussion started.

> so that the short form
>
>    (define-syntax (swap! a b)
>
> corresponds to the long form
>
>    (define-syntax swap!
>      (lambda (form)
>        (let ((a (cadr  form))
>              (b (caddr form)))
>
> and /not/
>
>    (define-syntax swap!
>      (lambda (_ a b) ....
>
> which I had before.

And after a bit of thought I fully endorse this change.

The short form is wonderful; we should keep it just as it is.

(1) It is not possible to make the relation of long form to short
form for |define-syntax| exactly parallel to that for |define|
without major changes to the language.  Given that they must be
different, it is less likely to cause confusion if the difference
is large.

(2) It is a long tradition that a macro has one argument which is
bound to the entire form of the macro call.  I think that both
LISP 1.5 and Common Lisp do it that way.

> While this latter (discarded) format would have been more brief
> for certain simple (especially lexical) macros, notice that it
> requires the input form to be a proper list and is therefore
> less general than the long form
>
>    (define-syntax swap!
>      (lambda (form)
>
> which can accept dotted lists or (perhaps in future) even single
> identifiers.

It seems that (lambda form ... ), without the parentheses, would
be just as general, and the short form is even briefer for the
simple cases.  But let's just forget that.  Macro procedures have
just one argument; that's easy to remember.

> The long form is now compatible with the SYNTAX-CASE system.

So there's a third reason.

> However, the short form above is not.  Indeed, I find the short form
>
>    (define-syntax (swap! a b)
>
> more useful than the relatively recently introduced SYNTAX-CASE one:
>
>    (define-syntax (swap! form)
>
> even though the latter would conform more to one's expectations from
> experience with DEFINE.

I agree that the first of those is better, it makes the definition
look like the thing it defines.  In fact, the second form seems
totally perverse.  Please make them stop.

My experience with |define| would lead me to expect that the
latter is a definition of a one-argument |swap!| macro.  If it is
not that (I assume), I am left wondering whether |form| is bound
to the entire call, or only to the argument list.  In either case,
what is the point?  You still need |car| and |cdr| to get the
arguments.

------
Random thoughts:

The appendix of R4RS says that it has been suggested (it doesn't
say by whom) that #'<datum> and #`<datum> would be felicitous
abbreviations for (syntax <datum>) and (quasisyntax <datum>).
Could this be added to the SRFI?

Since |syntax| is already analogous to |quote|, is |syntax-quote|
really the right name for the third way?  If I understood it
better, I might be able to name it better.  How about
|syntax-reuse|?

As a stylistic matter, I think it would be better to remove uses
of |syntax-case| and |with-syntax| from the examples, except
where comparison with |syntax-case| is the point of the example.

In particular, the example given under the description of
|syntax-quote| is confusing because it requires a rather deep
understanding of |syntax-case| in order to follow.  A better
example would be built out of the the forms defined by the
SRFI only.  I bet it would actually come out shorter that
way, but I won't venture to try to make the example this
close to midnight.  It would also help to have two examples,
identical except that one uses |syntax| and the other
uses |syntax-quote| with different results.

The link to Andrew Wright's pattern matcher
 http://download.plt-scheme.org/.../match.ss
at the end of kffd-match-tut.htm seems to be broken.

--
     -- Keith Wright

Programmer in Chief, Free Computer Shop
 ---  Food, Shelter, Source code.  ---