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
syntax-rules provides some syntax to effect this transformation
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
the fixnum addition operator, but Guile doesn’t have
fx+, you may use the
following to replace
(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.
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
(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:
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
#' syntax forms.