Re: Keywords reduced Marc Nieper-Wißkirchen 23 Oct 2019 07:18 UTC

Am Di., 22. Okt. 2019 um 21:33 Uhr schrieb John Cowan <xxxxxx@ccil.org>:
>
>
>
> On Tue, Oct 22, 2019 at 2:04 AM Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote:
>
>>
>> Apart from cleaner code, a syntax-case macro will retain source code
>> location information.
>
>
> "May", not "will".  R6RS-Libraries 12.2 says:  "A syntax object [...] may also be used by an implementation to maintain source-object correlation".

You are right; I was a bit sloppy with my language. However, I think
we agree that maintaining such source-object correlation is desirable,
e.g. for error messages and for debugging purposes. Syntax-case does
allow maintaining this correlation, while systems like
er-macro-transformer do not.

>> This is not only important for debugging but
>> makes it possible to write macros like the R7RS form `include', which
>> shall include the file from the directory where the source of the
>> include form comes from.
>
>
> Note that include in R7RS is non-hygienic: the code is interpolated as-is.

What do you mean by non-hygienic? (Some implementations, namely those
where identifiers are never bare symbols but always wrapped syntax
objects, have some kind of hygiene always built in.)

Let us consider the following piece of code:

(define-syntax foo
  (syntax-rules ()
    ((file) (include file))))

(define-syntax bar
  (syntax-rules ()
    (() (foo "file.scm"))))

(bar)

There are basically three possibilities for the syntactic environment,
in which the identifiers contained in "file.scm" are resolved: In the
syntactic environment of the macro use of "bar", in the
macro-environment resulting from the expansion of "bar" or in the
macro-environment resulting from the expansion of "foo".

The language of R7RS is not exactly clear on that matter, I think. It
could mean the first or the last possibility. Maybe the second.

I am still hoping that a future SRFI to be included in R7RS-large will
clarify this matter so that "include" becomes compatible with the rest
of the syntax system of R7RS.

Racket already shows us how to get a clear, composable and useful
semantics: https://docs.racket-lang.org/reference/include.html. The
primitive form is "include-at/relative-to", and "include" with clear
semantics can be derived from it.

>
>
>>
>> On the other hand, something like `syntax-e' can easily be implemented
>> on top of `syntax-case', so in any `syntax-case' system, you can use
>> your favorite pattern matcher.
>
>
> The rock-bottom core of a syntax-case system (per Eli Barzilay of Racket) is syntax, syntax->datum, datum->syntax, and either syntax-e or syntax-case.

Almost.

Consider:

(lambda (stx)
  (syntax-case stx ()
    (a #'(a b))))

If you want to rewrite this without `syntax-case', you will end up with:

(lambda (stx)
  (list stx #'b))

The difference between the two versions is that the first may return a
wrapped syntax object while the second will return an unwrapped syntax
object. When these procedures are used as macro transformers, this
doesn't make a difference. However, if the syntax object returned by
the first version is wrapped, it can contain source location
information for the whole form #'(a b), while the second version can
only maintain source location information for the two pieces stx (i.e.
#'a) and #'b.

Thus if we do not want to preclude the option to maintain the
source-object correlation, `syntax-case' is strictly more powerful
than `syntax-e' (which, incidentally, wasn't needed in the second
version because of the simplicity of the pattern to match).

Marc