On 04/06/2012 12:47 PM, Danny Yoo wrote:
I suspect that I should be using quote-syntax at this specific point,
but I am not completely sure.

Right. Try replacing ??? with (quote-syntax #,a-placeholder).


I have to admit that I'm still confused.  Here's my example:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket

(require racket/stxparam racket/splicing)

(define-syntax-parameter current-def #f)

(define-syntax (def stx)
  (syntax-case stx ()
    [(_ (name args ...) body ...)
     (with-syntax ([function-stx stx])
       (syntax/loc stx
         (define (name args ...)
           (splicing-syntax-parameterize ([current-def
                                           (quote-syntax
function-stx)])
             body ...))))]))

You moved the 'splicing-syntax-parameterize' back inside the scope of 'args'. That's why it doesn't work. Here's the correct version:

(define-syntax (def stx)
 (syntax-case stx ()
   [(_ (name args ...) body ...)
    (with-syntax ([function-stx stx])
      (syntax/loc stx
        (splicing-syntax-parameterize
            ([current-def (quote-syntax function-stx)])
          (define (name args ...)
            body ...))))]))

 From what I understand of quote-syntax, it should create a syntax
object that preserves the lexical information in function-stx.
function-stx should be a syntax object whose lexical information does
not include the function argument's variables.  Yet, when I run this,
the program prints 4, rather than 84 as I expected.

At the time 'def' is expanded, the lexical context of 'function-stx' does not include the bindings of 'args'. But then the macro produces an expression with that term inside a 'quote-syntax' form that is inside the scope of the 'args'. So by the time the expander gets to the 'quote-syntax' form, the lexical context of the original term has been enriched with the 'args' bindings.

In other words, the appearance of 'quote-syntax' in a macro template doesn't magically freeze the lexical context of its argument then and there. What matters is the lexical context when the expander reaches the 'quote-syntax' expression itself.

That's why (quote-syntax function-stx) needs to go outside the binding of the 'args'.

(There are tricks (eg, 3D syntax or syntax properties) that can hide the syntax from the expander so it doesn't get the 'args' wraps, but they're fragile. And hacky. Don't use them.)

Ryan
_________________________
 Racket Developers list:
 http://lists.racket-lang.org/dev

Reply via email to