[plt-scheme] Parameterizing expansion of subexpressions

From: Neil Toronto (ntoronto at cs.byu.edu)
Date: Tue Jan 19 14:33:21 EST 2010

What's the best way to parameterize the expansion of subexpressions? 
I've tried to make syntax parameters work, but I need the parameter 
values at expansion time, and it doesn't seem to be made for that.

Here's some example code that demonstrates a solution I've found so far, 
and hopefully the problem:

#lang scheme

(require (for-syntax syntax/parse)

(define-for-syntax current-value (make-parameter #'4))

(define-syntax (with-value stx)
   (syntax-parse stx
     [(_ val:expr e:expr)
      (parameterize ([current-value  #'val])
        (local-expand #'e (syntax-local-context) '()))]))

(define-syntax (the-value stx)
   (syntax-parse stx
     [(_)  (current-value)]))

(check-equal? (the-value) 4)

; this gives 16 without local-expand, because #'e is expanded
; outside the dynamic extent of parameterize:
(check-equal? (with-value (+ 4 5)
                 (sqr (the-value)))

In what I'm really working on, the parameter contains syntax used by 
macros like the-value at expansion time, which is (I think) why I can't 
get syntax parameters to work. I don't like using expanding #'e fully, 
mostly because I can't see the expansion in the macro stepper, but also 
because it seems too much like a sledgehammer.

I've also tried to make the-value a macro that gets shadowed using 
let-syntax. Of course let-values introduces a #'the-value that is not 
free-identifier=? to the original because of hygiene. Here's the naive, 
broken version:

(define-syntax the-value  (syntax-rules () [(_) 4]))

(define-syntax (with-value stx)
   (syntax-parse stx
     [(_ val:expr e:expr)
      #'(let-syntax ([the-value  (syntax-rules () [(_)  val])])

; fails: returns 16
(check-equal? (with-value (+ 4 5)
                 (sqr (the-value)))

Is there a nice way to make the-value shadow the-value?

Neil T

Posted on the users mailing list.