[plt-scheme] Parameterizing expansion of subexpressions
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)
schemeunit)
(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)))
81)
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])])
e)]))
; fails: returns 16
(check-equal? (with-value (+ 4 5)
(sqr (the-value)))
81)
Is there a nice way to make the-value shadow the-value?
Thanks!
Neil T