I’m attempting to create a “new” (i.e. not yet implemented in Snap!) data type: set. In many respects a set is like a list, so I started out implementing it as a list, with type-specific functions. Soon I ran unto trouble though; let me explain.
Unlike lists, sets are identical if their members are the same, irrespective of their order within the set. E.g. {1, 2} = {2, 1} - if I tell my set comparator that both inputs are sets, this can easily be dealt with. But what if the sets have subsets? E.g. {1, {1, 2}} = {1, {2, 1}} … but if sets are implemented as lists, there is no way for the code to discern {1, {1, 2}} from {1, (1, 2)} - the second structure being a set containing a list; and since order does matter where lists are concerned, (1, 2) ≠ (2, 1); consequently {1, (1, 2)} ≠ {1, (2, 1)).
One way to deal with this is writing a “deep” set comparator, that will assume all lists contained by sets are themselves sets. This excludes hybrid sets, containing both subsets and lists. Even if in most practical cases such hybrids will be exceptional, it doesn’t feel right to knowingly build an inconsistency into the code from the outset. So I’m looking for a different solution.
A second way to deal with it is along the “OOP with procedures” route (Ref.Manual, ch. viii). A variable referencing a set will thus be typed as a “command” by the predicate, so it’s easily discernible from a list. But how can it be discerned from other “commands” that are members of a set, or any of its subsets?
Or perhaps someone has a better suggestion for creating a new data type?