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

From: Michael W (mwilber at uccs.edu)
Date: Thu Apr 5 19:34:54 EDT 2012

Hey wow, maybe I might understand this. Or maybe I might be
totally wrong. Here's a guess:

In the first version, the (splicing-syntax-parameterize) takes
effect *when f is defined*; then, after the definition, the
parameter is reset to #f (and presumably it's lexical binding)
because it's a parameter? Nothing changes during the function
call.

But in the second version, the splicing-syntax-parameterize takes
effect during the dynamic extent of the function call, giving
(outer) a chance to extract the lexical scope of the function?

Maybe something like that?

3 hours ago, Danny Yoo wrote:
> 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?

-- 
I hope your galaxy is rotating at a pleasant rate,
    _mike

Posted on the dev mailing list.