
Is there a way to reliably convert a syntax object in a macro to runtime syntax object?
I’ve been using #'#'
, but I found today that this doesn’t work when the syntax object contains an ellipsis.

Use quote-syntax
. Always use quote-syntax
when you have a syntax constant instead of a syntax template that you want to interpret. (The issue you discovered is fundamentally the same as SQL injection, markup injection, etc, just in a different context.)

I’m trying to apply my own semantics to a Scribble reader using read-syntax-inside
. This example complains that #%datum
is not bound when running (run-at-expr (open-input-string "\n"))
, which makes sense. I thought I would be able to fix it with an (eval '(require (for-syntax racket/base)) ns)
or an equivalent namespace-require
, but it still fails with the same error. How am I supposed to ensure #%datum
and company are available in ns
below?
#lang racket
(require scribble/reader)
(define (run-at-expr in)
(define ns (make-base-namespace))
(define (port->sequence)
(in-list (syntax-e (read-syntax-inside (object-name in) in))))
(for/foldr ([acc '()]) ([expr (port->sequence)])
(printf "Eval: ~v~n" expr)
(define result (eval-syntax expr ns))
(unless (void? result)
(cons result acc))))

Replacing eval-syntax
with eval
fixes the example. It may or may not be what you want.

@deactivateduser60718 Maybe it is namespace-syntax-introduce
you are looking for? (define (run-at-expr in)
(define ns (make-base-namespace))
(define (port->sequence)
(parameterize ([current-namespace ns])
(in-list (syntax-e (namespace-syntax-introduce (read-syntax-inside (object-name in) in))))))
(for/foldr ([acc '()]) ([expr (port->sequence)])
(printf "Eval: ~v~n" expr)
(define result (eval-syntax expr ns))
(unless (void? result)
(cons result acc))))

Thanks! That works perfectly. I have a follow-up question. Will this have a problem once the code is bytecode-compiled (e.g., losing source location information)? I am told to look into transform-template
which is supposed to be a better way to handle things, but after reading the documentation and seeing some examples, I still don’t understand what it does, what problem it can solve, etc.