[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
6.10.6 Identifier Macros
When the syntax expander sees a form in which the first element is a macro, the whole form gets passed to the macro’s syntax transformer. One may visualize this as:
(define-syntax foo foo-transformer) (foo arg...) ;; expands via (foo-transformer #'(foo arg...))
If, on the other hand, a macro is referenced in some other part of a form, the syntax transformer is invoked with only the macro reference, not the whole form.
(define-syntax foo foo-transformer) foo ;; expands via (foo-transformer #'foo)
This allows bare identifier references to be replaced programmatically via a
macro. syntax-rules
provides some syntax to effect this transformation
more easily.
- Syntax: identifier-syntax exp
Returns a macro transformer that will replace occurrences of the macro with exp.
For example, if you are importing external code written in terms of fx+
,
the fixnum addition operator, but Guile doesn’t have fx+
, you may use the
following to replace fx+
with +
:
(define-syntax fx+ (identifier-syntax +))
There is also special support for recognizing identifiers on the
left-hand side of a set!
expression, as in the following:
(define-syntax foo foo-transformer) (set! foo val) ;; expands via (foo-transformer #'(set! foo val)) ;; if foo-transformer is a "variable transformer"
As the example notes, the transformer procedure must be explicitly marked as being a “variable transformer”, as most macros aren’t written to discriminate on the form in the operator position.
- Scheme Procedure: make-variable-transformer transformer
Mark the transformer procedure as being a “variable transformer”. In practice this means that, when bound to a syntactic keyword, it may detect references to that keyword on the left-hand-side of a
set!
.(define bar 10) (define-syntax bar-alias (make-variable-transformer (lambda (x) (syntax-case x (set!) ((set! var val) #'(set! bar val)) ((var arg ...) #'(bar arg ...)) (var (identifier? #'var) #'bar))))) bar-alias ⇒ 10 (set! bar-alias 20) bar ⇒ 20 (set! bar 30) bar-alias ⇒ 30
There is an extension to identifier-syntax which allows it to handle the
set!
case as well:
- Syntax: identifier-syntax (var exp1) ((set! var val) exp2)
Create a variable transformer. The first clause is used for references to the variable in operator or operand position, and the second for appearances of the variable on the left-hand-side of an assignment.
For example, the previous
bar-alias
example could be expressed more succinctly like this:(define-syntax bar-alias (identifier-syntax (var bar) ((set! var val) (set! bar val))))
As before, the templates in
identifier-syntax
forms do not need wrapping in#'
syntax forms.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on April 20, 2013 using texi2html 5.0.