(lispkit enum)

Library (lispkit enum) implements an API for enumeration types, enumeration values, and enumeration sets.

An enumeration type is defined by a list of tagged enumeration names. It encapsulates enumeration values which can be accesses either by name or ordinal value. Sets of these enumeration values are called enumeration sets. Each enumeration set is based on an enumeration type and contains a set of enumeration values.

Declarative API

The define-enum and define-enumeration forms defines an enumeration type and provide two macros for constructing its members and sets of its members.

type-name is an identifier that is bound as a syntactic keyword; symbol ... are the symbols that comprise the universe of the enumeration (in order).

(type-name symbol) checks whether the name of symbol is in the universe associated with type-name. If it is, (type-name symbol) is equivalent to symbol. It is a syntax violation if it is not.

constructor is an identifier that is bound to a syntactic form that, given any finite sequence of the symbols in the universe, possibly with duplicates, expands into an expression that evaluates to the enumeration set of those symbols.

(constructor symbol ...) checks whether every symbol ... is in the universe associated with type-name. It is a syntax violation if one or more is not. Otherwise (constructor symbol ...) is equivalent to ((enum-set-constructor (constructor-syntax)) '(symbol ...)).

Here is a complete example:

(define-enumeration color
  (black white purple maroon)
  color-set)
(color black)                 ⇒ black
(color purpel)                ⇒ error: symbol not in enumeration universe
(enum-set->list (color-set))  ⇒ ()
(enum-set->list
  (color-set maroon white))   ⇒ (white maroon)

Enum types

Returns #t if obj is an enum type, and #f otherwise.

Returns a newly allocated enum type containing a fixed set of newly allocated enums. Both enums and enum types are immutable, and it is not possible to create an enum except as part of creating an enum type. name is the name of the enumeration as a string or symbol, tag is an arbitrary object attached to the enum type (which can be accessed via enum-type-tag).

The elements of list are either symbols or two-element lists, where each list has a symbol as the first element and any value as the second element (this is the enum's tag). Each list element causes a single enum to be generated, and the enum's name is specified by the symbol. It is an error unless all the symbols are distinct within an enum type. The position of the element in list is the ordinal of the corresponding enum, so ordinals within an enum type are also distinct. If a value is given, it becomes the value of the enum; otherwise the enum’s value is the same as the ordinal.

Here are a few examples:

(define color
  (make-enum-type
    '(red orange yellow green cyan blue violet)))

(define us-traffic-light
  (make-enum-type '(red yellow green)))

(define pizza
  (make-enum-type
    '((margherita "tomato and mozzarella")
      (funghi "mushrooms")
      (chicago "deep-dish")
      (hawaiian "pineapple and ham"))))

Returns the type tag, i.e. an uninterned symbol, representing the type of enums as defined by enum-type.

Returns an exact integer equal to the number of enums in enum-type.

Returns the enum belonging to enum-type whose ordinal is 0.

Returns the enum belonging to enum-type whose ordinal is equal to the number of enums in the enum type minus 1.

Returns the tag associated with enum-type.

Returns a list of the enums belonging to enum-type ordered by increasing ordinal.

Returns a list of the names of the enums belonging to enum-type ordered by increasing ordinal.

Returns a list of the values of the enums belonging to enum-type ordered by increasing ordinal.

Returns #t if enum belongs to enum-type, and #f otherwise.

(enum-type-contains? color
  (enum-name->enum color 'red)) ⇒ #t
(enum-type-contains? pizza
  (enum-name->enum color 'red)) ⇒ #f

Returns a procedure which given an object, checks that this object is an enum that belongs to enum-type.

Returns a procedure which given an object, checks that this object is an enum set whose type matches enum-type.

If there exists an enum belonging to enum-type named symbol, returns it; otherwise return #f.

Returns the ordinal of the enum belonging to enum-type whose name is symbol. It is an error if there is no such enum.

Returns the value of the enum belonging to enum-type whose name is symbol. It is an error if there is no such enum.

If there exists an enum belonging to enum-type whose ordinal is exact-integer, returns it; otherwise return #f.

Returns the name of the enum belonging to enum-type whose ordinal is exact-integer. It is an error if there is no such enum.

Returns the value of the enum belonging to enum-type whose ordinal is exact-integer. It is an error if there is no such enum.

Enum values

Returns #t if obj is an enum, and #f otherwise.

Returns the enum type to which enum belongs.

Returns the name (symbol) associated with enum.

Returns the ordinal (exact integer) associated with enum.

Returns the tag associated with enum.

Returns the enum that belongs to the same enum type as enum and has an ordinal one greater than enum. Returns #f if there is no such enum.

(enum-name (enum-next color-red)) ⇒ orange
(enum-next (enum-max color))      ⇒ #f

Returns the enum that belongs to the same enum type as enum and has an ordinal one less than enum. Returns #f if there is no such enum.

Returns #t if all the arguments are the same enum in the sense of eq? (which is equivalent to having the same name and ordinal) and #f otherwise. It is an error to apply enum=? to enums belonging to different enum types.

(enum=? color-red color-blue)      ⇒ #f
(enum=? pizza-funghi
  (enum-name->enum pizza 'funghi)) ⇒ #t  
(enum=? color-red
  (enum-name->enum color 'red)
  color-blue)                      ⇒ #f  

These predicates return #t if their arguments are enums whose ordinals are in increasing, decreasing, non-decreasing, and non-increasing order respectively, and #f otherwise. It is an error unless all of the arguments belong to the same enum type.

Enum sets

Returns #t if obj is an enum set and #f otherwise.

Returns an enum set that can contain enums of the type enum-type and containing the enums. It is an error unless all the enums belong to enum-type.

(enum-set-contains?
  (enum-set color color-red color-blue)
  color-red)     ⇒  #t
(enum-set-contains?
  (enum-set color color-red color-blue)
  color-orange)  ⇒  #f

Returns an enum set with the specified enum-type that contains the members of list. list may contain enums, enum names, or enum ordinals. It is an error unless all the members refer to enums belonging to enum-type.

Returns a copy of enum-set.

Returns #t if enum-set is empty, and #f otherwise.

Returns #t if enum is a member of enum-set. It is an error if enum does not belong to the same enum type as the members of enum-set.

Returns #t if enum-set1 and enum-set2 do not have any enum objects in common, and #f otherwise.

(define reddish
  (list->enum-set
    (map (lambda (name) (enum-name->enum color name))
         '(red orange))))
(define ~reddish
  (list->enum-set
    (map (lambda (name) (enum-name->enum color name))
         '(yellow green cyan blue violet))))
(enum-set-disjoint? color-set reddish) ⇒ #f
(enum-set-disjoint? reddish ~reddish)  ⇒ #t

Projects enum-set1 into the universe of enum-set2, dropping any elements of enum-set1 that do not belong to the universe of enum-set2. If enum-set1 is a subset of the universe of its second, no elements are dropped, and the injection is returned.

(let ((e1 (make-enumeration '(red green blue black)))
      (e2 (make-enumeration '(red black white))))
  (enum-set->list (enum-set-projection e1 e2))))
⇒ (red black)

The enum-set-member? procedure returns #t if its first argument is an element of its second argument, #f otherwise.

The enum-set-subset? procedure returns #t if the universe of enum-set1 is a subset of the universe of enum-set2 (considered as sets of symbols) and every element of enum-set1 is a member of enum-set2. It returns #f otherwise.

(let* ((e (make-enumeration '(red green blue)))
       (c (enum-set-constructor e)))
  (list (enum-set-member? 'blue (c '(red blue)))
        (enum-set-member? 'green (c '(red blue)))
        (enum-set-subset? (c '(red blue)) e)
        (enum-set-subset? (c '(red blue)) (c '(blue red)))
        (enum-set-subset? (c '(red blue)) (c '(red)))
        (enum-set=? (c '(red blue)) (c '(blue red)))))
⇒ (#t #f #t #t #f #t)

Returns #t if the members of enum-set-1 are the same as of enum-set-2. It is an error if the members of the enum sets do not belong to the same type.

Returns #t if the members of enum-set-1 are a proper subset of enum-set-2. It is an error if the members of the enum sets do not belong to the same type.

Returns #t if the members of enum-set-1 are a proper superset of enum-set-2. It is an error if the members of the enum sets do not belong to the same type.

Returns #t if the members of enum-set-1 are a subset of enum-set-2. It is an error if the members of the enum sets do not belong to the same type.

Returns #t if the members of enum-set-1 are a superset of enum-set-2. It is an error if the members of the enum sets do not belong to the same type.

Returns a list of the names of enums that belong to enum-set. The list is in increasing order of the enums.

(let* ((e (make-enumeration '(red green blue)))
       (c (enum-set-constructor e)))
  (enum-set->list (c '(blue red))))
⇒ (red blue)

Returns a list containing the enum members of enum-set. The list is in increasing order of the enums.

(let* ((e (make-enumeration '(red green blue)))
       (c (enum-set-constructor e)))
  (enum-set->enum-list (c '(blue red))))
⇒ (#<enum enum-3: 0> #<enum enum-3: 2>)

Returns the ordinally next enum in enum-set following enum e. e is either a name, ordinal, or enum value. enum-set-next returns #f if there is no next enum.

Returns the enum type associated with enum-set.

Returns a bit set (as defined by library (lispkit bitset)) representing all ordinals of enum-set.

Returns the number of elements in enum-set.

Adds enums e ... to enum-set. Enums are defined either via a name, an ordinal, or an enum object. It is an error if the enums denoted by e ... do not all belong to the same enum type.

list is a list of enums. Enums are defined either via a name, an ordinal, or an enum object. enum-set-adjoin-all! adds all enums of list to enum-set. It is an error if the enums denoted by list do not all belong to the same enum type.

Removes enums e ... from enum-set. Enums are defined either via a name, an ordinal, or an enum object. It is an error if the enums denoted by e ... do not all belong to the same enum type.

list is a list of enums. Enums are defined either via a name, an ordinal, or an enum object. enum-set-delete-all! removes all enums of list from enum-set. It is an error if the enums denoted by list do not all belong to the same enum type.

Arguments enum-set1 and enum-set2 must be enumeration sets that have the same enumeration type.

The enum-set-union procedure returns the union of enum-set1 and enum-set2. The enum-set-intersection procedure returns the intersection of enum-set1 and enum-set2. The enum-set-difference procedure returns the difference of enum-set1 and enum-set2.

(let* ((e (make-enumeration '(red green blue)))
       (c (enum-set-constructor e)))
  (list (enum-set->list (enum-set-union (c '(blue)) (c '(red))))
        (enum-set->list
          (enum-set-intersection (c '(red green)) (c '(red blue))))
        (enum-set->list
         (enum-set-difference (c '(red green)) (c '(red blue))))))
⇒ ((red blue) (red) (green))

Procedure enum-set-xor returns the exclusive disjunction of enum-set1 and enum-set2. Arguments enum-set1 and enum-set2 must be enumeration sets that have the same enumeration type.

Returns enum-set's complement with respect to its universe.

(let* ((e (make-enumeration '(red green blue)))
       (c (enum-set-constructor e)))
  (enum-set->list (enum-set-complement (c '(red)))))
⇒ (green blue)

Creates the union of enum-set1 and enum-set2 and stores its result in enum-set1. enum-set1 and enum-set2 must be enumeration sets that have the same enumeration type.

Creates the intersection of enum-set1 and enum-set2 and stores its result in enum-set1. enum-set1 and enum-set2 must be enumeration sets that have the same enumeration type.

Creates the set difference between enum-set1 and enum-set2 and stores its result in enum-set1. enum-set1 and enum-set2 must be enumeration sets that have the same enumeration type.

Creates the exclusive disjunction between enum-set1 and enum-set2 and stores its result in enum-set1. enum-set1 and enum-set2 must be enumeration sets that have the same enumeration type.

Replaces enum-set with its complement with respect to the type of enum-set.

Returns a unary procedure that, given a symbol that is in the universe of enum-set, returns its 0-origin index within the canonical ordering of the symbols in the universe; given a value not in the universe, the unary procedure returns #f.

(let* ((e (make-enumeration '(red green blue)))
       (i (enum-set-indexer e)))
  (list (i 'red) (i 'green) (i 'blue) (i 'yellow)))
 ⇒ (0 1 2 #f)

The enum-set-indexer procedure could be defined as follows using the memq procedure:

(define (enum-set-indexer set)
  (let* ((symbols (enum-set->list (enum-set-universe set)))
         (cardinality (length symbols)))
    (lambda (x)
      (cond ((memq x symbols) =>
              (lambda (probe) (- cardinality (length probe))))
            (else #f)))))

Returns #t if any application of pred to the elements of enum-set returns true, and #f otherwise.

Returns #t if every application of pred to the elements of enum-set returns true, and #f otherwise.

Returns an exact integer, the number of elements of enum-set that satisfy pred.

Invokes proc on each member of enum-set in increasing ordinal order. The results are returned as a list.

Invokes proc on each member of enum-set in increasing ordinal order and discards the rest.

The current state is initialized to nil, and proc is invoked on each element of enum-set in increasing ordinal order and the current state, setting the current state to the result. The algorithm is repeated until all the elements of enum-set have been processed. Then the current state is returned.

Returns an enum set containing the enums in enum-set that satisfy pred.

Returns an enum set containing the enums in enum-set that do not satisfy pred.

R6RS Compatibility

Argument symbol-list must be a list of symbols. The make-enumeration procedure creates a new enumeration type whose universe consists of those symbols (in canonical order of their first appearance in the list) and returns that universe as an enumeration set whose universe is itself and whose enumeration type is the newly created enumeration type.

Returns the set of all symbols that comprise the universe of its argument enum-set, as an enumeration set.

Returns a unary procedure that, given a list of symbols that belong to the universe of enum-set, returns a subset of that universe that contains exactly the symbols in the list. The values in the list must all belong to the universe.

Given an enum set, enum-constructor returns a procedure which takes an enum name and returns the corresponding enum object.

Last updated