enum.texi 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. @node Enumerated/finite types and sets
  2. @section Enumerated/finite types and sets
  3. @i{(This section was derived from work copyrighted @copyright{}
  4. 1993--2005 by Richard Kelsey, Jonathan Rees, and Mike Sperber.)}
  5. @stindex finite-types
  6. @stindex enum-sets
  7. @texonlyindent
  8. The structure @code{finite-types} has two macros for defining
  9. @dfn{finite} or @dfn{enumerated record types}. These are record types
  10. for which there is a fixed set of instances, all of which are created
  11. at the same time as the record type itself. Also, the structure
  12. @code{enum-sets} has several utilities for building sets of the
  13. instances of those types, although it is generalized beyond the
  14. built-in enumerated/finite type device. There is considerable overlap
  15. between the @embedref{Boxed bitwise-integer masks,boxed bitwise-integer
  16. mask library} and the enumerated set facility.
  17. @subsection Enumerated/finite types
  18. @deffn syntax define-enumerated-type
  19. @lisp
  20. (define-enumerated-type @var{dispatcher} @var{type}
  21. @var{predicate}
  22. @var{instance-vector}
  23. @var{name-accessor}
  24. @var{index-accessor}
  25. (@var{instance-name}
  26. @dots{}))@end lisp
  27. This defines a new record type, to which @var{type} is bound, with as
  28. many instances as there are @var{instance-name}s. @var{Predicate} is
  29. defined to be the record type's predicate. @var{Instance-vector} is
  30. defined to be a vector containing the instances of the type in the same
  31. order as the @var{instance-name} list. @var{Dispatcher} is defined to
  32. be a macro of the form (@var{dispatcher} @var{instance-name}); it
  33. evaluates to the instance with the given name, which is resolved at
  34. macro-expansion time. @var{Name-accessor} & @var{index-accessor} are
  35. defined to be unary procedures that return the symbolic name & index
  36. into the instance vector, respectively, of the new record type's
  37. instances.
  38. For example,
  39. @lisp
  40. (define-enumerated-type colour :colour
  41. colour?
  42. colours
  43. colour-name
  44. colour-index
  45. (black white purple maroon))
  46. (colour-name (vector-ref colours 0)) @result{} black
  47. (colour-name (colour white)) @result{} white
  48. (colour-index (colour purple)) @result{} 2@end lisp
  49. @end deffn
  50. @deffn syntax define-finite-type
  51. @lisp
  52. (define-finite-type @var{dispatcher} @var{type}
  53. (@var{field-tag} @dots{})
  54. @var{predicate}
  55. @var{instance-vector}
  56. @var{name-accessor}
  57. @var{index-accessor}
  58. (@var{field-tag} @var{accessor} [@var{modifier}])
  59. @dots{}
  60. ((@var{instance-name} @var{field-value} @dots{})
  61. @dots{}))@end lisp
  62. This is like @code{define-enumerated-type}, but the instances can also
  63. have added fields beyond the name and the accessor. The first list of
  64. field tags lists the fields that each instance is constructed with, and
  65. each instance is constructed by applying the unnamed constructor to the
  66. initial field values listed. Fields not listed in the first field tag
  67. list must be assigned later.
  68. For example,
  69. @lisp
  70. (define-finite-type colour :colour
  71. (red green blue)
  72. colour?
  73. colours
  74. colour-name
  75. colour-index
  76. (red colour-red)
  77. (green colour-green)
  78. (blue colour-blue)
  79. ((black 0 0 0)
  80. (white 255 255 255)
  81. (purple 160 32 240)
  82. (maroon 176 48 96)))
  83. (colour-name (colour black)) @result{} black
  84. (colour-name (vector-ref colours 1)) @result{} white
  85. (colour-index (colour purple)) @result{} 2
  86. (colour-red (colour maroon)) @result{} 176@end lisp
  87. @end deffn
  88. @subsection Sets over enumerated types
  89. @deffn syntax define-enum-set-type
  90. @lisp
  91. (define-enum-set-type @var{set-syntax} @var{type}
  92. @var{predicate}
  93. @var{list->x-set}
  94. @var{element-syntax}
  95. @var{element-predicate}
  96. @var{element-vector}
  97. @var{element-index})@end lisp
  98. This defines @var{set-syntax} to be a syntax for constructing sets,
  99. @var{type} to be an object that represents the type of enumerated sets,
  100. @var{predicate} to be a predicate for those sets, and
  101. @var{list->x-set} to be a procedure that converts a list of elements
  102. into a set of the new type.
  103. @var{Element-syntax} must be the name of a macro for constructing set
  104. elements from names (akin to the @var{dispatcher} argument to the
  105. @code{define-enumerated-type} & @code{define-finite-type} forms).
  106. @var{Element-predicate} must be a predicate for the element type,
  107. @var{element-vector} a vector of all values of the element type, and
  108. @var{element-index} a procedure that returns the index of an element
  109. within @var{element-vector}.
  110. @end deffn
  111. @deffn procedure enum-set->list enum-set @returns{} element list
  112. @deffnx procedure enum-set-member? enum-set element @returns{} boolean
  113. @deffnx procedure enum-set=? enum-set@suba{a} enum-set@suba{b} @returns{} boolean
  114. @deffnx procedure enum-set-union enum-set@suba{a} enum-set@suba{b} @returns{} enum-set
  115. @deffnx procedure enum-set-intersection enum-set@suba{a} enum-set@suba{b} @returns{} enum-set
  116. @deffnx procedure enum-set-negation enum-set @returns{} enum-set
  117. @code{Enum-set->list} returns a list of elements within @var{enum-set}.
  118. @code{Enum-set-member?} tests whether @var{element} is a member of
  119. @var{enum-set}. @code{Enum-set=?} tests whether two enumerated sets
  120. are equal, @ie{} contain all the same elements. The other procedures
  121. perform standard set algebra operations on enumerated sets. It is an
  122. error to pass an element that does not satisfy @var{enum-set}'s
  123. predicate to @code{enum-set-member?} or to pass two enumerated sets of
  124. different types to @code{enum-set=?} or the enumerated set algebra
  125. operators.
  126. @end deffn
  127. Here is a simple example of enumerated sets built atop the enumerated
  128. types described in the previous section:
  129. @lisp
  130. (define-enumerated-type colour :colour
  131. colour?
  132. colours
  133. colour-name
  134. colour-index
  135. (red blue green))
  136. (define-enum-set-type colour-set :colour-set
  137. colour-set?
  138. list->colour-set
  139. colour colour? colours colour-index)
  140. (enum-set->list (colour-set red blue))
  141. @result{} (#@{Colour red@} #@{Colour blue@})
  142. (enum-set->list (enum-set-negation (colour-set red blue)))
  143. @result{} (#@{Colour green@})
  144. (enum-set-member? (colour-set red blue) (colour blue))
  145. @result{} #t@end lisp