Changeset 33994 in project


Ignore:
Timestamp:
04/18/17 14:14:01 (8 months ago)
Author:
juergen
Message:

read-macro trick added to explicit-renaming-macros

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/explicit-renaming-macros

    r32941 r33994  
    147147operator.
    148148
     149The last version is easy to write, because the macro is small. There are
     150only three symbols to be renamed.
     151
     152But what if you have a giant macro with dozens of symbols to be renamed?
     153It's not a problem to prefix them all with ,% in the replacement text,
     154but then you have to add a giant let defining the renamed symbols.  And
     155this is cumbersome indeed.
     156
     157Wouldn't it be nice, if this additional let could be added
     158automatically?  Well, there is a trick to achieve this. It's based on
     159read-macros.
     160
     161You can add a read-macro with (set-read-syntax! chr proc) just before
     162the macro definition and remove it with (set-read-syntax! chr #f) after
     163the definition. But if chr were already set to read-syntax before, the
     164former call would override and hence destroy it. So a better way is to
     165save and restore the whole read-table, which is done with the parameter
     166current-read-table, which stores all read-macros.
     167
     168So here is a version of swap! using this trick.
     169
     170<enscript highlight="scheme">
     171;; save read-table
     172(define old-crt (copy-read-table (current-read-table)))
     173
     174;; define read-macro
     175(set-read-syntax! #\%
     176                  (lambda (port)
     177                    (let ((xpr (read port)))
     178                      (if (symbol? xpr)
     179                        `(rename ',xpr)
     180                        xpr))))
     181
     182;; define macro
     183(define-syntax swap!
     184  (er-macro-transformer
     185    (lambda (form rename compare?)
     186      (let ((x (cadr form))
     187            (y (caddr form)))
     188        `(,%let ((,%tmp ,x))
     189           (,%set! ,x ,y)
     190           (,%set! ,y ,%tmp))))))
     191
     192;; restore read-table
     193(current-read-table old-crt)
     194</enscript>
     195
     196You can convince yourself that renaming has taken place without being
     197defined explicitly by simply issuing (pp (expand '(swap! x y))) as above.
     198
    149199We havn't used the compare? argument in the transformer in this example.
    150200What's its role?
Note: See TracChangeset for help on using the changeset viewer.