Index: doc/proposals/enums.md
===================================================================
--- doc/proposals/enums.md	(revision 46c4deae2f30b239301bab9eba643e6846b4983d)
+++ doc/proposals/enums.md	(revision 46c4deae2f30b239301bab9eba643e6846b4983d)
@@ -0,0 +1,133 @@
+Enumeration Type Proposals
+==========================
+With Jiada's recent work on enumerations (see doc/theses/jiada_liang_MMath/),
+this is a collection point for some remaining issues with and ideas to
+further improve enumerations.
+
+Fixed Encoding
+--------------
+Because Cforall enumerations are encoded using their position, it can be
+difficult to give them a stable encoding. The
+
+The example (provided by Gregor Richards), is a system header that defines
+any type that has to be stable across versions. Let's say error codes.
+
+```cfa
+enum() BigLibError! {
+	BadArgument,
+	...
+	MissingConfig,
+	LastStartupError = MissingConfig,
+	NoMemory,
+	Timeout,
+	...
+};
+```
+
+The actual errors are not important, but note that "LastStartupError" has
+to be in a particular location relative to some others. If a new version of
+the header wants to add a new startup error, it should go before the
+LastStartupError, but that will change the position, and hence the encoding,
+of all the remaining
+
+The most obvious example in an existing lanuage I could find is that Rust
+usually treats its enum types as opaques algebraic data types, but in certain
+cases allows you to fix the encoding of enumerations.
+(Although the motivation seems to be optimization of enumerations that
+have a lot of common options.)
+
+Enumerated Arrays
+-----------------
+Arrays that use an enumeration as their index. The entire enumeration type
+(instead of a subset of int) is used in the index operation.
+
+Although described differently, this is actually a generalization of typed
+enumerations, as it can be used to safely represent a constant of any type
+for each possible enumeration value.
+
+```cfa
+extern string colourNames[Colour];
+```
+
+This example is a forward declaration that declares the symbol but does not
+give the values or allocate any storage. This is used in header files.
+The type of colourNames would be a new type `string[Colour]`.
+
+In implementation tiles it is safe to give the array's values;
+whether it the array has been previously forward declared or not.
+```cfa
+string colourNames[Colour] = {
+  "red",
+  "violet",
+  "blue",
+  // Or without worrying about ordering:
+  [Green] = "green",
+  [Orange] = "orange",
+  [Yellow] = "yellow",
+};
+```
+
+The forward declaration and full definition variants allow the user to manage
+memory themselves, following the same rules as `extern` variables.
+The user can use `const` to fix the values in the array.
+These arrays can also be nested `BlendInfo blend[Colour][Colour]` or used
+locally.
+
+Except for the index type (and that the size of the array is fixed per
+index type, as it always covers the whole enumeration) it should be the same
+as a traditional array.
+
+Or one of the new safer Cforall arrays, as the features could be combined.
+
+(Previously, a compined declaration to declare both an enumeration and
+an enumerated array was proposed. That only covers the simple case that
+typed enumerations already cover.)
+
+Enumeration Ranges
+------------------
+We have the simplest iterate over a range of enumerations (can only be used
+directly in a for loop, always covers the entire type) but it could be
+generalized to work with the other features of ranges, such as going over
+just part of the enumeration (see Ranges in doc/proposals/iterators.md).
+
+Flag Set Enumerations
+---------------------
+Another common use of enumerations is as a named bitset.
+
+This doesn't actually follow from the logical definition of enumerations, but
+is something that various implementation of "enum" have commonly been used to
+recreate. This would formalize that, providing an easy way to create typesafe
+implementations of this pattern.
+
+```cfa
+enum Directions flag {
+  Up,
+  Down,
+  Left,
+  Right,
+  Upwards = Up,
+  Vertical = Up | Down,
+};
+```
+
+Uses the existing enumeration syntax, except that all initializers must be
+bitwise expressions, using only the operators |, & and ~ and, as leaf values,
+other labels from the enumeration (no cycles) and 0.
+
+Each uninitialized label creates a new flag. Every instance of the
+enumeration will have each flag be set or unset. The labels act as instances
+of the enumeration with only that flag set.
+
+A type created this way automatically supports: default construction,
+from zero_t construction, copy construction, copy assignment, destruction,
+equality, inequality and bitwise and (&), or (|) and not (~).
+Default construction and from zero_t construction create an instance with no
+flags set. Two instances are the same if the same flags are set.
+Bitwise operations act on the individual flags in the set.
+
+In addition the type can be converted to a Boolean.
+An flag set is truthy if any flags are set and falsy if no flags are set.
+This is not a primitive operation, but comes from combining the zero_t
+constructor and inequality.
+
+Note: Scoping rules are also waiting on the namespacing and module system.
