apparent bug in sample implementation of SRFI 148
William D Clinger 18 Jul 2017 17:17 UTC
It looks to me as though the sample implementations of SRFI 147
and/or SRFI 148 are relying on non-portable behavior by the native
macro system. In the following example, I will ignore hygienic
renamings because the problem has mainly to do with structure, not
hygiene.
Consider the following example, which is part of the first test
in the test program for SRFI 148.
(let-syntax ((m
(em-syntax-rules ()
((m 'a) 'a))))
(m '(define x 10))
x)
To find the boundary between definitions and expressions, it
is necessary to expand the (em-syntax-rules () ((m 'a) 'a))
part, which turns into something like
(em-syntax-rules-aux1
free-identifier=?
()
...
()
(((m 'a) 'a)))
which turns into something like
(em-syntax-rules-aux2
free-identifier=?
()
...
()
(((m 'a) 'a)))
which turns into something like
(begin
(define-syntax
o
(em-syntax-rules-aux2
o
free-identifier=?
()
...
()
(((m 'a) 'a))
()))
o)
That is not legal in R7RS (small). You can't use a macro
keyword as though it were an expression.
SRFI 147 extends R7RS (small) by allowing macro keywords to
be used in certain contexts, but the sample implementation of
SRFI 147 does not export the begin keyword, so begin has its
usual R7RS (small) meaning in libraries that import (srfi 147).
In particular, the "begin" introduced by the em-syntax-rules-aux2
macro of the sample implementation of SRFI 148 has its usual R7RS
(small) meaning, so that macro doesn't work in systems that check
for the error of using a syntactic keyword as though it were an
expression.
Whether this should be regarded as an error in the sample
implementation of SRFI 147 or SRFI 148 or both may be unclear,
but it seems pretty clear that the result of combining those
two sample implementations is not portable R7RS (small) code.
Will