tutorial.scm 5.2 KB

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