Re: apparent bug in sample implementation of SRFI 148
William D Clinger 19 Jul 2017 15:41 UTC
Marc Nieper-Wißkirchen wrote:
> The "c" is inserted here:
>
> https://github.com/scheme-requests-for-implementation/srfi-147/blob/master/srfi/147.scm#L135
>
> By hygiene, in each rule of the partial expansion above, the first and
> third "c" are equal identifiers; the second one (that, which is not
> followed by ":::2") is a different "c".
>
> I guess, this is the "c", which appears here:
>
> (letrec-syntax
> ((m
> (syntax-rules ()
> ((m a)
> (em (em-quote
> (em-if (em-free-identifier=? 'a 'm) 'true 'false)))))))
> (m c))
>
> Could you test with your latest version what happens when that "c" is
> renamed to something different (a symbol not used elsewhere)?
Oh, that's interesting:
> (import (srfi 2) (srfi 26) (srfi 147) (srfi 148))
>
(letrec-syntax
((m
(syntax-rules ()
((m a)
(em (em-quote
(em-if (em-free-identifier=? 'a 'm) 'true 'false)))))))
(m ddddd))
false
It looks to me as though the "c" inserted by line 135 of 147.scm
has the same meaning as the "c" in the test (because neither is
bound in the context where they are inserted) so free-identifier=?
recognizes them as equivalent. From R6RS 11.19:
A literal identifier matches an input subform if and only
if the input subform is an identifier and either both its
occurrence in the input expression and its occurrence in
the list of literals have the same lexical binding, or the
two identifiers have the same name and both have no lexical
binding.
R7RS 4.3.2:
An element in the input matches a literal identifier if and
only if it is an identifier and either both its occurrence
in the macro expression and its occurrence in the macro
definition have the same lexical binding, or the two
identifiers are the same and both have no lexical binding.
The R6RS is more precise here, with the "have the same name"
explaining what the R7RS leaves open to more imaginative
interpretations by saying "are the same".
Your diagnosis is confirmed by adding the following definition
to 147.scm:
(define c #f) ; right-hand side is arbitrary
With that one-line change, all of your tests pass.
You had already added a definition for :continuation, which was
necessary because it's used as a literal and you didn't want it
to match if that name happens to appear within a use. It's less
obvious that you need to do the same for other names that occur
free within your macro-defining macros, so they can't clash with
pattern literals originating in a use, but you do need to do
that.
Will