[racket] getting one macro to tell another macro to define something
It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms.
In this case, sender would be
(define-syntax (sender stx)
(syntax-case stx ()
[(_ def) #'(begin-for-syntax (set-add! (syntax-parameter-value #'current-defs) #'def))]))
You would need your test to instead use splicing-syntax-parameterize to get the use of sender at the top level.
You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce.
All together this is
#lang racket
(require racket/stxparam
racket/splicing
(for-syntax syntax/parse
racket/set))
;; current-defs : (syntax-parameter-of (or/c set-mutable? #f))
(define-syntax-parameter current-defs #f)
(define-syntax (sender stx)
(syntax-case stx ()
[(_ def) #`(begin-for-syntax (set-add! (syntax-parameter-value #'current-defs) #'def))]))
(define-syntax reciever
(lambda (stx)
(syntax-parse stx
[(reciever)
(define defs (syntax-parameter-value #'current-defs))
(with-syntax ([(def ...) (set-map defs syntax-local-introduce)])
#'(begin def ...))])))
(splicing-syntax-parameterize ([current-defs (mutable-set)])
(sender (define x 1))
(reciever)
x)
-Ian
----- Original Message -----
From: "Alexander D. Knauth" <alexander at knauth.org>
To: "racket users list" <users at racket-lang.org>
Sent: Friday, August 1, 2014 5:12:00 PM GMT -05:00 US/Canada Eastern
Subject: [racket] getting one macro to tell another macro to define something
Is there any way to do something like this and have it work?:
#lang racket
(require racket/stxparam
(for-syntax syntax/parse
racket/set))
;; current-defs : (syntax-parameter-of (or/c set-mutable? #f))
(define-syntax-parameter current-defs #f)
(define-syntax sender
(lambda (stx)
(syntax-parse stx
[(sender def)
(define defs (syntax-parameter-value #'current-defs))
(set-add! defs #'def)
#'(void)])))
(define-syntax reciever
(lambda (stx)
(syntax-parse stx
[(reciever)
(define defs (syntax-parameter-value #'current-defs))
(with-syntax ([(def ...) (set->list defs)])
#'(begin def ...))])))
(syntax-parameterize ([current-defs (mutable-set)])
(sender (define x 1))
(reciever)
x)
Right now, x is undefined.
I’m guessing that that’s because it has the wrong syntax marks, but is there any way around that?
(Other that doing (datum->syntax stx (syntax->datum …)) on everything?)
____________________
Racket Users list:
http://lists.racket-lang.org/users