racket

Unbound Identifier Racket


#lang racket

(define-syntax unpack
  (syntax-rules ()
    [(unpack) (begin (define x 1))]))

(unpack)

(+ x 1)

Why is it that I am getting an error: x: unbound identifier in: x?

After defining the macro, I expect the code to define x appropriate w/o error? I can't seem to figure this out, could it be an issue with the syntax or compiler?


Solution

  • The macro expander intentionally works this way to avoid accidentally interfering with the x in the outer context.

    One way to tell the expander you actually want to use the outer x is to pass it in.

    (define-syntax unpack
      (syntax-rules ()
        [(_ id) (begin (define id 1))]))
    
    (unpack x)
    

    Another way is to use datum->syntax to construct an identifier x in the same context in which the usage of unpack appears.

    (define-syntax (unpack stx)
      (syntax-case stx ()
        [(k)
         (with-syntax ([id (datum->syntax #'k 'x)])
           #'(begin (define id 1)))]))
    
    (unpack)