For Development HEAD DRAFTSearch (procedure/syntax/module):

5.5 Syntax parameters

Syntax parameters allows to rebind syntactic binding dynamically during macro expandsion. The form resembles parameterize (see Parameters), but works purely at macro expansion time. It allows to define a macro that affects other macros hygienically. It is defined by SRFI-139.

Suppose you want to have a macro (block <body> ...) that evaluates expression <body> sequentially. Inside it, we want to have another macro (return <expr>), which evaluates <expr> and then exits (block ...), making the value of <expr> as the value of (block ...),

In other words, the macro block need to change the behavior of return. It can be written, for example, as follows:

(define-syntax block
  (er-macro-transformer
    (^[f r c]
      (quasirename r
       `(let/cc ,'return ,@(cdr f)))))

(block (print 1) (print 2) (return 'oops) (print 4))
 ⇒ print 1, 2, and then returns oops

But note that this needs to insert return unhyginenically. It may break, for example, when combined with another library that uses return for other purposes.

With syntax parameters, you can write it hygienically:

(define-syntax-parameter return
  (syntax-rules ()
    ((_ . _) (syntax-error "return outside block"))))

(define-syntax block
  (syntax-rules ()
    ((_ body ...)
     (let/cc %return
       (syntax-parameterize ((return (syntax-rules ()
                                       ((_ expr) (%return expr)))))
         body ...)))))

The return has desired effect with block only if it refers to the same bindings of define-syntax-parameter. Suppose you make the above code into a library, and the user imports the library with prefix. Then, the user can refer to the non-local-exit return with the prefix, and that can coexist of whatever return defined in the user’s module.

(use block :prefix b:)

(define return ...)

(b:block
  ...
  (return ...)  ; This refers to the 'return' in the current module
  ...
  (b:return 'oops) ; This invokes 'return' to exit from the block
  ...
  )
Special Form: define-syntax-parameter name transformer-spec

[SRFI-139] Like define-syntax, binds name with a macro created by transformer-spec, but the binding is marked as a syntax parameter, and can be altered with syntax-parameterize.

The given transformer-spec works as a default macro, invoked when no syntax-parameterize on name is in effect. The forms allowed in transformer-spec is the same as define-syntax.

Special Form: syntax-parameterize ((key transformer-spec) …) body …

[SRFI-139] The keys must be identifiers bound to syntax parameters. This form alters the macro transformers of keys with the ones specified by the given transformer-specs, then proceed to compile body …. The altered bindings are effective during the dynamic scope of macro-expansion phase. (Be aware that it has nothing to do with the dynamic scope at runtime.)



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT