0

I'm trying to use syntax parameters in order to inject new syntax where I need it to be injected. The result of this is then used in other syntax. However, it's not working as I expect it to. Here's a minimal working example:

(require racket/stxparam)
(require (for-syntax racket/stxparam))

;; declare parameter to be replaced with code
(define-syntax-parameter placeholder
  (lambda (stx)
    (raise-syntax-error
     (syntax-e stx)
     "can only be used inside declare-many-commands")))

;; this is just to print what 'arg' looks like
(define-syntax (print-syntax stx)
  (syntax-case stx ()
    [(_ arg)
     #'(displayln 'arg)]))

;; this is the top-level entity invoked to produce many commands
(define-syntax-rule (declare-many-commands cmds)
  (begin
    (let ([X 10])
      (syntax-parameterize
       ([placeholder (make-rename-transformer #'X)])
       cmds))
    (let ([X 20])
      (syntax-parameterize
       ([placeholder (make-rename-transformer #'X)])
       cmds))))

(declare-many-commands
 (print-syntax placeholder))

What I would like to get as result when running this is:

10
20

but what I get is:

placeholder
placeholder

EDIT:

Posted a new question to refine the problem: Injecting syntax at compile time using Racket's syntax parameters?

gablin
  • 4,678
  • 6
  • 33
  • 47

1 Answers1

2

The problem here is that your print-syntax macro quotes its input, and inputs to macro transformers are unexpanded syntax. This means that the expansion of (print-syntax placeholder) will always be (displayln 'placeholder), and no macroexpansion ever occurs under quote, so the placeholder binding in scope is irrelevant.

If you want to use the syntax parameter, you need to actually produce a reference to the placeholder binding. In this case, you just need to remove the use of quote. You could change print-syntax to (displayln arg), but at that point, there’s really no reason for print-syntax to be a macro, since it’s equivalent to the displayln function. Just use that instead:

(declare-many-commands
 (displayln placeholder))

This will print 10 and 20 as you expect.

It’s possible you really do want the quote, and I don’t understand your question. In that case, though, I think it’s difficult for me to understand what you’re getting at without some additional context.

Alexis King
  • 43,109
  • 15
  • 131
  • 205
  • It was apparently a bad example that I gave in the question. I've now updated it using code from the actual application to better illustrate the problem. – gablin Apr 26 '18 at 08:38
  • @gablin A few things. First of all, it is considered bad form to significantly rewrite your question in a way that invalidates existing answers, even if your initial question wasn’t the one you wanted to ask. Just ask a new question. Second, your code seems wildly overcomplicated, since you’re using a lot of very low-level operations instead of high-level things like `syntax/parse`. Third, I don’t think I can answer your question without an understanding of what `define-instruction` itself does, so can you please include a real implementation instead of a dummy one? Then I’d be willing to try. – Alexis King Apr 26 '18 at 15:13
  • Alright, I've rolled back the question to its original state and posted a new question: https://stackoverflow.com/q/50047354/426092 – gablin Apr 26 '18 at 15:56