On Friday, August 18, 2017 at 1:11:16 AM UTC-4, Alexis King wrote:
> > On Aug 17, 2017, at 21:52, Sam Waxman <samwax...@gmail.com> wrote:
> > 
> > On a related note, I've read that read-syntax is supposed to return a
> > syntax-object whose lexical context is stripped. Why is that? Doesn't
> > that make it impossible for the language to know the difference
> > between the let I used in an earlier file and the let that the user
> > types as an identifier?
> 
> Yes, this is likely the cause of your problem (and it’s what I guessed
> was probably going on before you sent the second post). This is, for
> better or for worse, currently a no-no in Racket — syntax objects
> produced by a #lang’s reader are supposed to only have source locations
> and syntax properties on them, not lexical context.
> 
> There are various reasons this can be explained, some historical, others
> technical. One explanation I’ve heard is that valid programs read by
> `read-syntax` are supposed to also be valid programs if read by `read`
> — this means lexical context shouldn’t matter. In practice, I think this
> is probably not a very strong argument (I think `read`’s existence and
> its relationship to the #lang protocol is mostly a historical artifact
> in Racket), but there are also questions about the meaning of syntax
> objects with lexical context that have not yet been seen by the
> macroexpander. Those technical details are outside of my realm of
> knowledge, but I can at least offer some solutions.
> 
> Generally, my recommendation is to essentially define your language in
> two passes: a direct translation to s-expressions, followed by a phase
> of macroexpansion. The first phase is what your reader interacts with.
> Give the primitives that your reader produces names that are unlikely
> to conflict with users’ code — specifically, prefix them with “#%” so
> that they are clearly special. It can also be useful to include
> characters in the identifier names that aren’t even valid identifier
> characters in your language, but this is not always possible if any
> character can be legally used in an identifier. Either way, this means
> your my-let macro should likely be named something like #%let or
> #%my-language-let, and your reader produce syntax objects without
> lexical context that use these #%-prefixed primitives.
> 
> The good news is, once you have converted your #lang’s source syntax to
> s-expressions, you can hand those expressions off to the macroexpander,
> and then you can use whatever hygienic names you wish. You can define
> your #%-prefixed primitives as hygienic macros that expand to
> nicely-scoped syntax objects with lexical context. For example, in a
> non-s-expression language I implemented in Racket, I converted lambda
> syntax into uses of a #%lambda form, and since the language supported
> pattern-matching, I defined #%lambda as a macro that expanded to plain
> old match-lambda** from racket/match. At that point, the name will not
> conflict, because macroexpansion is hygienic.
> 
> It feels a little inelegant that Racket’s hygiene system does not extend
> to read-time, since it means the sort of hacks necessary in unhygienic
> languages are sometimes necessary in Racket when implementing a reader.
> Fortunately, a reader is much more self-contained and smaller in scope
> than a macro-enabled language, so it usually isn’t a big deal. Perhaps
> some language will eventually motivate a hygienic reader layer, but
> Racket doesn’t current have one.

Wow, I'm very surprised that the reader doesn't have hygiene! Seems odd that 
you can't do a number of things if your language's identifiers are allowed to 
have all the characters present in racket's.

Thankfully my languages doesn't allow # or % to be id characters, so I can do 
as you say and just prefix my macros with them. Thanks! 

-- 
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.

Reply via email to