Ah, I didn't realize syntax-case allows a single identifier, and R6RS transformers are invoked even the macro keyword isn't appear in the first position of a list.  Now that makes sense.  Thanks.



On Mon, Mar 2, 2020 at 11:48 PM Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote:
Am Di., 3. März 2020 um 10:19 Uhr schrieb Shiro Kawai <xxxxxx@gmail.com>:
(syntax-rules (<literal> ...) <syntax-rule> ...)
and
<syntax-rule> := (<srpattern> <template>)

<srpattern> must be a list or a vector.   It can't be just an underscore (at least in R[567]RS).

For R[57]RS without extensions this is certainly true because there is no identifier syntax in the standard. For R6RS, it is true for the default implementation of `syntax-rules', but not for `syntax-case'. As it doesn't really have anything to do with `syntax-case', I chose to use the `syntax-rules' syntax. But you are right in that to have a portable R6RS example, I would have to use the more general patterns of `syntax-case'.

 

An implementation may have such extension, but I wonder... if a pattern (_ x y) matches the macro call (foo a b), then just a single identifier should match the entire macro call form?

If the expander is about to expand a form of the form `(keyword x y)' where `keyword' is bound to a transformer, the syntax argument to the transformer will be the entire form `(keyword x y)'. Thus a pattern of just `k' would match the entire form.

If the expander is about to expand an identifier (that does not appear in head position) `keyword', where `keyword' is bound to a transformer, the the syntax argument to the transformer will just be `keyword'. Thus a pattern of `k' would just match the keyword.

Does this answer your question? Or did I miss something?

Thanks,

Marc


On Mon, Mar 2, 2020 at 11:06 PM Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote:
Am Di., 3. März 2020 um 10:01 Uhr schrieb Shiro Kawai <xxxxxx@gmail.com>:
Can you define foo as an ordinary macro _and_ R6RS-style identifier syntax simultaneously?  I thought I can't.

What do you mean by an ordinary macro?

It is all about the pattern to be matched:

(define-syntax foo
  (syntax-rules ()
    ((_ x y) ...)
    (_ ...)))

If `foo' is used as `(foo x y)', the first clause will be expanded; if `foo' is used in any other context, the second clause will be used.

An example could be:

(define-syntax +
  (syntax-rules ()
    ((_ x y) (fast-binary-plus x y))
    (_ slow-general-plus)))

Such a syntax could be exported by, say `(scheme base)', and could make a lot of sense.

With the same trick, we could also make passing keyword arguments across library boundaries fast.

Marc


On Mon, Mar 2, 2020 at 10:57 PM Lassi Kortela <xxxxxx@lassi.io> wrote:
>         The difference is not subtle at all: macros resemble procedures
>         only in the general appearance of an invocation.  Lambda defines
>         a procedure, and even though there is no kw-apply, you can still
>         retrofit keywords to procedures and apply those procedures to
>         regular positional arguments without breaking them.
>
>     I agree with you that we would give up the ability of retrofitting
>     and that this would make keyword arguments much less useful.
>
> Having thought about this once more, I have to retract this point. With
> identifier syntax, it is very well possible to retrofit procedures with
> keyword arguments. A procedure with keyword arguments, even if it
> implemented as syntax, can still evaluate to an ordinary procedure when
> not used as a macro keyword.

This would require adding identifier syntax to R7RS-large, as you noted.

Unless I have misunderstood something, identifier syntax is basically
the same as symbol macros in Common Lisp. I Liked having them, but they
always seemed like there could be weird edge cases that blow up
unexpectedly. I never encountered any concrete problems with it, but
always felt like it shouldn't work that easily :)

One important use I'd like to preserve with kw args is higher-order
functions. With the current 177 you can make a lambda/kw and pass it to
another procedure that can call it using any of these:

- (foo args...)
- (apply foo args...)
- (call/kw foo args... (kws...))

That makes things really simple for users. I don't see a way to preserve
all of these possibilities without identifier syntax. Since 177 needs to
be usable immediately, it can't rely on new kinds of macros. That means
177 should probably specify lambda/kw to return real lambdas.

However, call/kw could be extended so it's allowed to call things that
are not real lambdas. Since call/kw is a macro that just expands to (foo
...), anything that is a valid procedure or macro call in the underlying
Scheme implementation should in principle work? I just thought of this
idea for the first time and may not understand all the details.




--
Prof. Dr. Marc Nieper-Wißkirchen
 
Universität Augsburg
Institut für Mathematik
Universitätsstraße 14
86159 Augsburg
 
Tel: 0821/598-2146
Fax: 0821/598-2090
 
E-Mail: xxxxxx@math.uni-augsburg.de
Web: www.math.uni-augsburg.de/alg/mitarbeiter/mnieper/