It's true that `internal-definition-context-binding-identifier` is unusual in not applying `syntax-local-introduce` to the identifiers it returns, but that doesn't capture the whole problem. Let's imagine we made things consistent by mapping `syntax-local-introduce` over the returned names. Let's also, though, bind an identifier that has an extra scope that should make it distinct from the `var` we look up:
#lang racket (define-for-syntax (sanity-check var) (define ctx (syntax-local-make-definition-context)) (syntax-local-bind-syntaxes (list ((make-syntax-introducer) var)) #f ctx) (cond ; should be non-#f; we just bound it! [(member (internal-definition-context-introduce ctx var) (map syntax-local-introduce (internal-definition-context-binding-identifiers ctx)) free-identifier=?) 'ok] [else (error "failed check")])) (define-syntax (m1 stx) #`'#,(sanity-check #'test)) (m1) We find that they're `free-identifier=?`, even though we added the extra scope to the binder! The problem here is that neither `(internal-definition-context-introduce ctx var)` or the identifiers in `(map syntax-local-introduce (internal-definition-context-binding-identifiers ctx))` now have the introduction scope, because we've removed it to match the "negative space" within the macro where syntax without an introduction scope should be considered introduced, rather than the "postive space" outside of the macro where the introduction scope means it the syntax was introduced. So when `free-identifier=?` resolves each of the two references, it finds them both unbound. And unbound references with the same symbol are `free-identifier=?`. To get the right answer, you need to ask `free-identifier=?` of identifiers in "positive space". In this case you should write: (member (syntax-local-introduce (internal-definition-context-introduce ctx var)) (internal-definition-context-binding-identifiers ctx) free-identifier=?) On Tuesday, July 24, 2018 at 8:32:56 AM UTC-4, Matthew Flatt wrote: > > At Tue, 24 Jul 2018 00:47:19 -0700 (PDT), Milo Turner wrote: > > Hello Racketeers. > > > > I'm having trouble understanding why this free-identifier=? check is > > failing: [...] > > > > This suggests that internal definition contexts are aware of the macro > > introduction scope in some way. The documentation doesn't mention this > sort > > of thing, so I'm wondering if there is some explanation I'm missing? > > I think it's a documentation issue, or perhaps a design issue with > `internal-definition-context-binding-identifiers`. > > Various operations implicitly use `syntax-local-introduce`, and I have > never been clear on when/where that needs to be specified. For example, > `local-expand` implicitly uses `syntax-local-introduce` on its > argument, because that's going back out of the current macro in a > sense, and it uses `syntax-local-introduce` again on the result. The > implicit uses of `syntax-local-introduce` make things "just work", and > so the uses are normally not mentioned in the documentation. > > Occasionally, however, there's a mismatch. In this case, > `syntax-local-bind-syntaxes` implicitly uses `syntax-local-introduce` > on its argument, but `internal-definition-context-binding-identifiers` > doesn't use `syntax-local-introduce` on its result. I think that's the > mismatch you're seeing. > > Overall, the documentation should be improved/corrected to mention the > implicit `syntax-local-introduce`s, and then exceptions like > `internal-definition-context-binding-identifiers` can be highlighted. > > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.