[racket-dev] some surprising behavior with syntax-parameterize and lexical info

From: Danny Yoo (dyoo at cs.wpi.edu)
Date: Thu Apr 5 16:15:36 EDT 2012

I'm hitting some behavior I don't understand: here's code to demonstrate:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#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 ([lexical-stx (datum->syntax stx 'lexical)])
       (syntax/loc stx
         (splicing-syntax-parameterize ([current-def #'lexical-stx])
            (define (name args ...)
               body ...))))]))

(define-syntax (outer stx)
  (syntax-case stx ()
    [(_ id)
     (datum->syntax (syntax-parameter-value #'current-def)
                    (syntax-e #'id))]))
(define x 42)
(def (f x) (* (outer x) x))
(f 2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

vs:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#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 ([lexical-stx (datum->syntax stx 'lexical)])
       (syntax/loc stx
         (define (name args ...)
           (splicing-syntax-parameterize ([current-def #'lexical-stx])
             body ...))))]))

(define-syntax (outer stx)
  (syntax-case stx ()
    [(_ id)
     (datum->syntax (syntax-parameter-value #'current-def)
                    (syntax-e #'id))]))
(define x 42)
(def (f x) (* (outer x) x))
(f 2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


The only difference is that the use of splicing-syntax-parameterize
has been moved closer to the body expressions.  I expected these two
programs to show the same output (84), but they don't.  Does anyone
know why?

Posted on the dev mailing list.