Chapter 12 Key Takeaways

Enumerated Types

  • Enumerated types create new types by listing every possible value by name: type TDay = (Monday, Tuesday, ..., Sunday);
  • Each value has an ordinal number starting from 0. Use Ord(value) to retrieve it.
  • Enumerations are ordinal types, supporting Succ, Pred, Low, High, comparison operators, and for loops.
  • The compiler enforces type safety — you cannot assign a TColor value to a TDay variable.
  • Use the prefix convention (ecFood, tlRed) or {$scopedenums on} to avoid name collisions between different enumerated types.
  • Enumerations make excellent array indices: var Hours: array[TDay] of Integer; creates a self-documenting, bounds-checked array.
  • Pair enumerations with case statements for exhaustiveness checking — the compiler warns if you miss a value.

Subrange Types

  • Subrange types restrict an ordinal type to a contiguous range: type TMonth = 1..12;
  • Enable {$R+} (range checking) during development to catch out-of-range assignments as runtime errors instead of silent bugs.
  • Subranges work with integers, characters, and enumerations: TWeekday = Monday..Friday;
  • Subranges as array indices create arrays with exactly the right number of elements and no invalid index access.

Sets

  • A set is an unordered collection of distinct elements from an ordinal base type: type TDays = set of TDay;
  • Set literals use square brackets: [Monday, Wednesday, Friday] or [1..5].
  • The in operator tests membership: if Today in Weekend then — cleaner and faster than chains of comparisons.
  • Set operators: + (union), * (intersection), - (difference).
  • Set comparisons: = (equal), <> (not equal), <= (subset), >= (superset).
  • Include(S, x) and Exclude(S, x) add/remove single elements efficiently.
  • The empty set is [].

Implementation

  • Sets are stored as bit vectors — each possible element is one bit (0 = absent, 1 = present).
  • Set operations map to single CPU instructions (OR, AND, AND NOT, bit test), making them extremely fast.
  • Maximum set size is 256 elements (ordinal values 0..255). This works perfectly for enumerations and characters.
  • A set of Char uses 32 bytes. A set of TDay fits in 1 byte.

Best Practices

  • Replace magic numbers with enumerations wherever you have a fixed set of named options.
  • Use {$R+} during development; only disable it for performance-critical code after thorough testing.
  • Use set of Char constants for character classification (vowels, digits, whitespace, etc.).
  • Use the subset operator (<=) for "has all required permissions" checks.
  • Prefer Include/Exclude over +/- when modifying a set by a single element.
  • Define character class sets as const for reuse and clarity.

PennyWise Project Progress

  • Replaced string-based expense categories with TExpenseCategory enumeration.
  • Added TCategoryFilter = set of TExpenseCategory for flexible report filtering.
  • Used enum-indexed arrays (array[TExpenseCategory] of Real) for category totals.
  • Set operations enable combining, intersecting, and differencing filters in a single expression.