ck-macro.scm 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. ;; Code from http://okmij.org/ftp/Scheme/macros.html#ck-macros
  2. ;; Added: A lot of comments trying to explain how this CK-machine
  3. ;; works.
  4. ;; The macro implements a stack based machine. It internally manages a
  5. ;; stack. It uses syntax-rule to build this stack based machine. So it
  6. ;; uses facilities, which are described as not composing well, to
  7. ;; build a foundation for something that does compose well. Some sort
  8. ;; of building from minimalistic concepts. Really clever stuff.
  9. ;; The macro performs evaluations of the stack elements towards the
  10. ;; goal of expanding ck-macros recursively.
  11. ;; Meaning of the identifiers:
  12. ;; - s: stack
  13. ;; - op: name of a CK-macro to do the reduction
  14. ;; - va: zero or more values
  15. ;; - v: a single value
  16. ;; - ea: zero or more arbitrary expressions
  17. ;; - ea1: one arbitrary expression
  18. ;; ===========
  19. ;; Explanation
  20. ;; ===========
  21. ;; The macro uses s, the stack. A stack frame on this stack looks as
  22. ;; follows:
  23. ;; ((op va ...) ea ...)
  24. ;; So basically there is a call to a CK-macro on top of the stack
  25. ;; being "destructured" into some parts:
  26. ;; a CK-macro -- op
  27. ;; zero or more values -- va ...
  28. ;; other arbitrary expressions -- ea ...
  29. ;; To evaluate, the core CK-macro needs to evaluate the other
  30. ;; arbitrary expressions.
  31. ;; ----------------------------------
  32. ;; WHAT DOES CHICKEN SCHEME WIKI SAY?
  33. ;; ----------------------------------
  34. ;; http://wiki.call-cc.org/eggref/5/ck-macros#what-are-ck-macros:
  35. ;; > Quoting is how the core ck macro knows the difference between a
  36. ;; value and a CK-macro call. Therefore, all values must be quoted,
  37. ;; even values which normally do not need to be quoted in Scheme code,
  38. ;; such as strings, numbers, and booleans.
  39. ;; > The core ck macro expands the input arguments ahead of time, so
  40. ;; the arguments will always be quoted values by the time your macro
  41. ;; is expanded.
  42. ;; > The quoted value is either used as an argument to another
  43. ;; CK-macro, or if your CK-macro is the outer-most CK-macro call, then
  44. ;; the core ck macro expands into the unquoted value.
  45. ;; > Eventually, your CK-macro must expand into a call to the core ck
  46. ;; macro with a quoted value.
  47. (define-syntax ck
  48. ;; Declaring quote as literal means, that whenever a quote is
  49. ;; encountered in a match expression, it cannot be a placeholder for
  50. ;; something else, but is expected to be exactly quote and nothing
  51. ;; else. It is literally quote, that is why it is called a literal.
  52. (syntax-rules (quote)
  53. ;; CASE 1: EMPTY STACK
  54. ;; "yield the value on empty stack"
  55. ;; If there is nothing more to evaluate, simply return the value.
  56. ;; The value is unquoted!
  57. ((ck () 'v) v)
  58. ;; CASE 2: ??? TODO
  59. ;; "re-focus on the other argument, ea"
  60. ;; Match structure:
  61. ;; - call to the ck macro with
  62. ;; - something: (((op ...) ea ...) . s)
  63. ;; - a stack frame?: ((op ...) ea ...)
  64. ;; - the rest of the stack now bound to s
  65. ;; - and a single value: 'v
  66. ;; Question: Why do we focus the ea and not the arguments of op?
  67. ;; Question: How does (op ...) work in matching of syntax-rules?
  68. ;; Answer: When the ellipsis ... follows some identifier, it
  69. ;; means, that there can be 0 or more things in the input to match
  70. ;; the identifier. In the output of the match case these things
  71. ;; are put where the ellipsis following the same identifier in the
  72. ;; output is.
  73. ;; Question: Why is this "arg" thing added?
  74. ;; Beginning of an answer: We match anything that has the following structure:
  75. ;; 1. An arbitrary number of things including the CK-macro op.
  76. ;; 2. At some point an arbitrary number of arbitrary expressions starts.
  77. ;; This is a very general matching it seems.
  78. ;; 1: the top-most stack frame is destructured as ((op ...) ea ...)
  79. ;; 2: s is rest of the stack.
  80. ;; Question: Why is 'v outside of the stack?
  81. ;; Answer: 'v represents the input of the called CK-macro.
  82. ;; Question: Why is ea already outside of the op call parentheses?
  83. ;; Answer: ???
  84. ((ck (((op ...) ea ...) . s) 'v)
  85. (ck s "arg" (op ... 'v) ea ...))
  86. ;; CASE 3: SINGLE CK-MACRO WITH ARGUMENTS REMAINING
  87. ;; "all arguments are evaluated do the redex"
  88. ;; I have no idea what exactly a redex is, but when all CK-macros
  89. ;; are evaluated, there is no need for recursively evaluating more
  90. ;; macros and we have a non-CK-macro expression left. This we
  91. ;; output as part of the over-all CK-macro expansion / evaluation
  92. ;; process. This is probably the step before the stack is empty.
  93. ;; Question: What is a redex?
  94. ;; Answer: Redex is short for "reducible expression". So when Oleg
  95. ;; writes "do the redex", he probably means, that we evaluate the
  96. ;; CK-macro that is op. That will be another expansion step, which
  97. ;; is some kind of "reduction", thus reducing the expression of
  98. ;; calling op.
  99. ((ck s "arg" (op va ...))
  100. (op s va ...))
  101. ;; CASE 4: TAKE A VALUE BACK INSIDE THE CALL TO OP AS ARGUMENT.
  102. ;; "optimization when the first ea was already a value."
  103. ;; 1: quote is declared a literal in this syntax-rules macro. As
  104. ;; written in the Chicken Scheme wiki, quoted things are
  105. ;; recognized by the ck core macro as values. Matching against a
  106. ;; literal quote ensures, that the identifier is really bound to a
  107. ;; value.
  108. ;; 2: ea1 could probably also be named simply ea, as it does not
  109. ;; ensure, that there is at least 1 arbitrary expression. However,
  110. ;; it is conceptually not the same, as it is not the whole
  111. ;; sequence of things, but the sequence minus the first element,
  112. ;; which is matched by 'v.
  113. ;; Question: Why is the 'v taken "inside", as an argument to the
  114. ;; macro call op?
  115. ;; Answer: "arg" actually indicates, that 'v was an argument
  116. ;; before this expansion step! So it _must_ be moved back inside
  117. ;; the call of op, after making sure it is expanded and a value!
  118. ;; Once it is expanded to a value (meaning it is quoted), the CK
  119. ;; machine does not need to expand it more.
  120. ((ck s "arg" (op ...) 'v ea1 ...)
  121. (ck s "arg" (op ... 'v) ea1 ...))
  122. ;; CASE 5: ???
  123. ;; "focus on ea, to evaluate it"
  124. ;; 1: ((op ...) ea1 ...) is put on top of the stack.
  125. ;; 2: ea stays outside the op parentheses.
  126. ((ck s "arg" (op ...) ea ea1 ...)
  127. (ck (((op ...) ea1 ...) . s) ea))
  128. ;; CASE 6: PREPARE TO EVALUATE ARGUMENTS
  129. ;; "Focus: handle an application; check if args are values"
  130. ;; Question: Why is this "arg" thing added?
  131. ;; Answer: ea ... are the arguments to the call of the CK-macro
  132. ;; op. If they are macros themselves, they need to be expanded
  133. ;; before op is evaluated. Thus they are moved outside the call
  134. ;; and the fact, that they are arguments of the call is denoted by
  135. ;; the "arg" string.
  136. ((ck s (op ea ...))
  137. (ck s "arg" (op) ea ...))))