> On Oct 21, 2020, at 10:33 AM, William G Hatch <wil...@hatch.uno> wrote:
>
> On Wed, Oct 21, 2020 at 10:07:12AM -0700, Kevin Forchione wrote:
>> Hi guys,
>> Suppose I have a macro that computes a value and then calls another macro in its template. Is there a way to share that data with the 2nd macro without passing it as an argument?
>
> Take a look at syntax parameters and syntax-local-value.
>
> Syntax parameters, somewhat similar to `parameterize` for runtime
> code, allow macros to have an implicit communication channel. The
> macro that `syntax-parameterize`es sets a value for the given
> parameter which is usually accessed by simply using the syntax
> parameter in its template somewhere. The syntax parameter may even be
> passed in to the macro as an argument and thus end up in the template.
> This is how `this` gets its value in the class macro -- it's a syntax
> parameter.
>
> However, if you want an inner macro to be able to inspect the value
> given to a syntax parameter, it can use `syntax-parameter-value` to
> get the current value out and do something with it.
>
> `syntax-local-value` is another useful tool for macros to communicate.
> When you `define-syntax` an identifier, you give it a transformer
> binding. Usually the value is a procedure (a macro transformer), but
> it can actually be other data. One popular type of data to use is a
> struct that implements `prop:procedure`, and can thus act as a macro
> transformer as well as a storage place for data (which can be
> inspected by the struct's procedure interface or by other code). To
> access this data, you pass the identifier (as a syntax object) that
> you `define-syntax`ed to `syntax-local-value`.
>
> Without knowing more about what you're trying to do I'm not sure what
> more concrete advice I can give, but syntax parameters and
> `syntax-local-value` are two of the killer features that make Racket's
> macro system so powerful, so I recommend anyone who wants to use
> macros to become familiar with them.
Here’s a toy example. It generates an error, but hopefully conveys the idea I’m trying to express.
#lang racket
(require (for-syntax syntax/parse)
racket/stxparam
racket/stxparam-exptime)
(define-syntax-parameter mval 1)
(define-syntax (foo stx)
(syntax-parse stx
[(_ m:number n:number)
#'(syntax-parameterize ([mval m])
(bar n))]))
(define-syntax (bar stx)
(syntax-parse stx
[(_ n) #'(* (syntax-parameter-value mval) n)]))
(foo 3 5)
Kevin