tutorial.scm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. ;; FROM: https://www.gnu.org/software/guile/manual/html_node/Defining-Macros.html#Defining-Macros
  2. ;; global syntax definition
  3. (define-syntax when
  4. (syntax-rules ()
  5. ((when condition exp ...)
  6. (if condition
  7. (begin exp ...)))))
  8. ;; local syntax definition
  9. (let-syntax ([unless (syntax-rules ()
  10. ((unless condition exp ...)
  11. (if (not condition)
  12. (begin exp ...))))])
  13. (unless #t
  14. (primitive-exit 1))
  15. "rock rock rock")
  16. (letrec-syntax ([my-or
  17. (syntax-rules ()
  18. ((my-or)
  19. #t)
  20. ((my-or exp)
  21. exp)
  22. ((my-or exp rest ...)
  23. (let ((t exp))
  24. (if t
  25. t
  26. (my-or rest ...)))))])
  27. (my-or #f "rockaway beach"))
  28. ;; EXAMPLE 2
  29. ;; kwote as alias for quote
  30. (define-syntax kwote
  31. (syntax-rules ()
  32. ((kwote exp)
  33. (quote exp))))
  34. (kwote (foo . bar))
  35. ;; EXAMPLE 3
  36. ;; let macro
  37. ;; matching improper lists
  38. (define-syntax let1
  39. (syntax-rules ()
  40. ((_ (var val) . exps) ; apparently one can use the _ to match
  41. ; the name of the macro (?)
  42. ; exps is second part of a pair
  43. ; it is a pattern
  44. ; In fact, it does not matter what we write
  45. ; as first part in the match case for
  46. ; syntax-rules.
  47. (let ((var val)) . exps))))
  48. ;; problem: it would match (let1 (foo 'bar) . baz)
  49. ;; Why is that a problem?
  50. ;; improved version
  51. (define-syntax let1
  52. (syntax-rules ()
  53. ((_ (var val) exp ...) ; exp ... will match the so called body
  54. (let ((var val)) exp ...))))
  55. ;; problem: body can be empty
  56. ;; further improved version
  57. (define-syntax let1
  58. (syntax-rules ()
  59. ((_ (var val) exp exp* ...) ; A common idiom is to name the
  60. ; ellipsized pattern variable with
  61. ; an asterisk.
  62. (let ((var val)) exp exp* ...))))
  63. ;; EXAMPLE 4
  64. ;; matching vectors
  65. (define-syntax letv ; let vector
  66. (syntax-rules ()
  67. ((_ #((var val) ...) exp exp* ...)
  68. (let ((var val) ...) exp exp* ...))))
  69. (letv #((foo 'bar)) foo)
  70. ;; EXAMPLE 5
  71. ;; What goes into the parentheses of syntax-rules?: syntax-rules (???)
  72. ;; Literals!
  73. ;; Parts which are matched against literally.
  74. ;; Not interpreted as "standing for a pattern".
  75. ;; That is how we can distinguish between literally meant stuff and
  76. ;; stuff that stands for patterns.
  77. (define-syntax cond1
  78. (syntax-rules (=> else) ; The following things are to be taken literally:
  79. ; => else
  80. [(cond1 test => fun)
  81. (let ((exp test))
  82. (if exp
  83. (fun exp) ; apply fun to the tested argument
  84. #f))]
  85. [(cond1 test exp exp* ...) ; if we have multiple expressions,
  86. ; we can use begin to run them all
  87. (if test
  88. (begin exp
  89. exp*
  90. ...))]
  91. [(cond1 else exp exp* ...) ; if we have an else we do not need to test more
  92. (begin exp
  93. exp*
  94. ...)]))
  95. (define (square x)
  96. (* x x))
  97. (cond1 10 => square) ; 100
  98. (let ((=> #t)) ; => is used as variable containing #t
  99. (cond1 10 => square)) ; will go into the multiple expressions case
  100. ;; EXAMPLE 6
  101. ;; Defining a macro, which defines macros.
  102. (define-syntax define-matcher-macro
  103. (syntax-rules ()
  104. ((_ name lit) ; expecting form:
  105. ; (define-matcher-macro
  106. ; <something-containing-a-name>
  107. ; <something-containing-a-literal>)
  108. (define-syntax name ; if it is a match, define the syntax (<some-name> ...
  109. (syntax-rules ()
  110. ((_ lit) #t) ; true if it is applied to the literal in lit
  111. ((_ else) #f) ; false otherwise
  112. )))))
  113. (define-matcher-macro is-literal-foo? "foo")
  114. (is-literal-foo? "foo")
  115. ⇒ #t
  116. (is-literal-foo? "bar")
  117. ⇒ #f
  118. (let ((foo "foo"))
  119. (is-literal-foo? foo))
  120. ⇒ #f
  121. ;; EXAMPLE 7
  122. ;; TODO: Explain how this even works!
  123. ;; Reporting errors at macro-expansion time (read time, compile time).
  124. (define-syntax simple-let
  125. (syntax-rules ()
  126. [(simple-let (head ... ((x . y) val) . tail)
  127. ; (1) head ... can also be zero times?
  128. ; (2) what is `. tail` matching?
  129. ; (3) can I not use two ellipsis on the
  130. ; same level instead of `. tail`?
  131. body1
  132. body2 ...)
  133. (syntax-error "expected an identifier but got"
  134. (x . y))]
  135. ;; if there ((a . b) val) is not matched
  136. [(simple-let ((name val) ...)
  137. body1
  138. body2 ...)
  139. ((lambda (name ...)
  140. body1
  141. body2 ...)
  142. val ...)]))
  143. ;; simply working
  144. (simple-let ([a 3])
  145. (+ a 4))
  146. ;; caught
  147. (simple-let ([(a . b) 3]) ; Q: What is `. tail` matching in this one?
  148. (+ a 4))
  149. (simple-let ([a 3] [(b . c) 3]) ; Q: What is `. tail` matching in this one?
  150. (+ a b))
  151. ;; not caught
  152. (simple-let ([a 3] [(b . c) 3] [d 4]) ; Q: Why is `. tail` not matching `[d 4]`?
  153. (+ a b))
  154. ;; EXAMPLE 8
  155. ;; Specifying a Custom Ellipsis Identifier.
  156. (define-syntax define-quotation-macros
  157. (syntax-rules ()
  158. ((_ (macro-name head-symbol) ...) ; arbitrary number of macro-name head-symbol pairs
  159. ; which will be defined.
  160. ; macro-name is not a literal.
  161. (begin (define-syntax macro-name
  162. (syntax-rules
  163. ::: () ; the ellipsis identifier can be given as a first
  164. ; argument to syntax-rules before the parentheses.
  165. ((_ x :::)
  166. (quote (head-symbol x :::)))))
  167. ...))))
  168. (define-quotation-macros
  169. (quote-a a)
  170. (quote-b b)
  171. (quote-c c)) ; define multiple macros, one for each given pair
  172. ; (quote-a 1 2 3) ⇒ (a 1 2 3)