macros.texi 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. @node Macros in concert with modules
  2. @section Macros in concert with modules
  3. One reason that the standard Scheme language does not support a module
  4. system yet is the issue of macros and modularity. There are several
  5. issues to deal with:
  6. @itemize @bullet
  7. @cindex separate compilation
  8. @item
  9. that compilation of code that uses macros requires presence of those
  10. macros' definitions, which prevents true separate compilation, because
  11. those macros may be from other modules;
  12. @cindex hygiene of macros in modules
  13. @cindex referential transparency of macros in modules
  14. @cindex macro hygiene in modules
  15. @cindex macro referential transparency in modules
  16. @item
  17. that a macro's expansion must preserve referential transparency and
  18. hygiene, for example in cases where it refers to names from within the
  19. module in which it was defined, even if those names weren't exported;
  20. and
  21. @cindex phase separation
  22. @cindex towers of evaluation phases
  23. @item
  24. that a macro's code may be arbitrary Scheme code, which in turn can use
  25. other modules, so one module's compile-time, when macros are expanded,
  26. is another's run-time, when the code used in macros is executed by the
  27. expander: this makes a tower of phases of code evaluation over which
  28. some coherent control must be provided.
  29. @end itemize
  30. @noindent
  31. Scheme48's module system tries to address all of these issues
  32. coherently and comprehensively. Although it cannot offer @emph{total}
  33. separate compilation, it can offer incremental compilation, and
  34. compiled modules can be dumped to the file system & restored in the
  35. process of incremental compilation.@footnote{While such facilities are
  36. not built-in to Scheme48, there is a package to do this, which will
  37. probably be integrated at some point soon into Scheme48.}
  38. Scheme48's module system is also very careful to preserve non-local
  39. module references from a macro's expansion. Macros in Scheme48 are
  40. required to perform hygienic renaming in order for this preservation,
  41. however; @pxref{Explicit renaming macros}. For a brief example,
  42. consider the @code{delay} syntax for lazy evaluation. It expands to a
  43. simple procedure call:
  44. @lisp
  45. (delay @var{expression})
  46. @expansion{} (make-promise (lambda () @var{expression}))@end lisp
  47. @noindent
  48. However, @code{make-promise} is not exported from the @code{scheme}
  49. structure. The expansion works correctly due to the hygienic renaming
  50. performed by the @code{delay} macro transformer: when it hygienically
  51. renames @code{make-promise}, the output contains not the symbol but a
  52. special token that refers exactly to the binding of @code{make-promise}
  53. from the environment in which the @code{delay} macro transformer was
  54. defined. Special care is taken to preserve this information. Had
  55. @code{delay} expanded to a simple S-expression with simple symbols, it
  56. would have generated a free reference to @code{make-promise}, which
  57. would cause run-time undefined variable errors, or, if the module in
  58. which @code{delay} was used had its @emph{own} binding of or imported a
  59. binding of the name @code{make-promise}, @code{delay}'s expansion
  60. would refer to the wrong binding, and there could potentially be
  61. drastic and entirely unintended impact upon its semantics.
  62. @cindex reflective tower
  63. @cindex syntactic tower
  64. @cindex @code{for-syntax}
  65. Finally, Scheme48's module system has a special design for the tower of
  66. phases, called a @dfn{reflective tower}.@footnote{This would be more
  67. accurately named `syntactic tower,' as it has nothing to do with
  68. reflection.} Every storey represents the environment available at
  69. successive macro levels. That is, when the right-hand side of a macro
  70. definition or binding is evaluated in an environment, the next storey
  71. in that environment's reflective tower is used to evaluate that macro
  72. binding. For example, in this code, there are two storeys used in the
  73. tower:
  74. @lisp
  75. (define (foo ...bar...)
  76. (let-syntax ((baz ...quux...))
  77. ...zot...))@end lisp
  78. @noindent
  79. In order to evaluate code in one storey of the reflective tower, it is
  80. necessary to expand all macros first. Most of the code in this example
  81. will eventually be evaluated in the first storey of the reflective
  82. tower (assuming it is an ordinary top-level definition), but, in order
  83. to expand macros in that code, the @code{let-syntax} must be expanded.
  84. This causes @code{...quux...} to be evaluated in the @emph{second}
  85. storey of the tower, after which macro expansion can proceed, and long
  86. after which the enclosing program can be evaluated.
  87. @cindex @code{for-syntax}
  88. The module system provides a simple way to manipulate the reflective
  89. tower. There is a package clause, @code{for-syntax}, that simply
  90. contains package clauses for the next storey in the tower. For
  91. example, a package with the following clauses:
  92. @lisp
  93. (open scheme foo bar)
  94. (for-syntax (open scheme baz quux))@end lisp
  95. @noindent
  96. has all the bindings of @code{scheme}, @code{foo}, & @code{bar}, at the
  97. ground storey; and the environment in which macros' definitions are
  98. evaluated provides everything from @code{scheme}, @code{baz}, &
  99. @code{quux}.
  100. With no @code{for-syntax} clauses, the @code{scheme} structure is
  101. implicitly opened; however, if there are @code{for-syntax} clauses,
  102. @code{scheme} must be explicitly opened.@footnote{This is actually only
  103. in the default config package of the default development environment.
  104. The full mechanism is very general.} Also, @code{for-syntax} clauses
  105. may be arbitrarily nested: reflective towers are theoretically infinite
  106. in height. (They are internally implemented lazily, so they grow
  107. exactly as high as they need to be.)
  108. Here is a simple, though contrived, example of using @code{for-syntax}.
  109. The @code{while-loops} structure exports @code{while}, a macro similar
  110. to C's @code{while} loop. @code{While}'s transformer unhygienically
  111. binds the name @code{exit} to a procedure that exits from the loop.
  112. It necessarily, therefore, uses @embedref{Explicit renaming macros,
  113. explicit renaming macros} in order to break hygiene; it also, in the
  114. macro transformer, uses the @code{destructure} macro to destructure the
  115. input form (@pxref{Library utilities}, in particular, the structure
  116. @code{destructuring} for destructuring S-expressions).
  117. @lisp
  118. (define-structure while-loops (export while)
  119. (open scheme)
  120. (for-syntax (open scheme destructuring))
  121. (begin
  122. (define-syntax while
  123. (lambda (form r compare)
  124. (destructure (((WHILE test . body) form))
  125. `(,(r 'CALL-WITH-CURRENT-CONTINUATION)
  126. (,(r 'LAMBDA) (EXIT)
  127. (,(r 'LET) (r 'LOOP) ()
  128. (,(r 'IF) ,test
  129. (,(r 'BEGIN)
  130. ,@@body
  131. (,(r 'LOOP)))))))))
  132. (CALL-WITH-CURRENT-CONTINUATION LAMBDA LET IF BEGIN))))@end lisp
  133. This next @code{while-example} structure defines an example procedure
  134. @code{foo} that uses @code{while}. Since @code{while-example} has no
  135. macro definitions, there is no need for any @code{for-syntax} clauses;
  136. it imports @code{while} from the @code{while-loops} structure only at
  137. the ground storey, because it has no macro bindings to evaluate the
  138. transformer expressions of:
  139. @lisp
  140. (define-structure while-example (export foo)
  141. (open scheme while-loops)
  142. (begin
  143. (define (foo x)
  144. (while (> x 9)
  145. (if (integer? (sqrt x))
  146. (exit (expt x 2))
  147. (set! x (- x 1)))))))@end lisp