source: doc/theses/jiada_liang_MMath/relatedwork.tex @ 4fa7096

Last change on this file since 4fa7096 was 4fa7096, checked in by Peter A. Buhr <pabuhr@…>, 8 weeks ago

small changes

  • Property mode set to 100644
File size: 62.5 KB
Line 
1\chapter{Related Work}
2\label{s:RelatedWork}
3
4Enumeration-like features exist in many popular programming languages, both past and present, \eg Pascal~\cite{Pascal}, Ada~\cite{Ada}, \Csharp~\cite{Csharp}, OCaml~\cite{OCaml} \CC, Go~\cite{Go}, Haskell~\cite{Haskell} \see{discussion in \VRef{s:AlgebraicDataType}}, Java~\cite{Java}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}.
5Among these languages, there is a large set of overlapping features, but each language has its own unique extensions and restrictions.
6
7
8\section{Pascal}
9\label{s:Pascal}
10
11Pascal introduced the \lstinline[language=Pascal]{const} aliasing declaration binding a name to a constant literal/expression.
12\begin{pascal}
13const Three = 2 + 1;   NULL = NIL;   PI = 3.14159;   Plus = '+';   Fred = 'Fred';
14\end{pascal}
15As stated, this mechanism is not an enumeration because there is no specific type (pseudo enumeration).
16Hence, there is no notion of a (possibly ordered) set.
17The type of each constant name (enumerator) is inferred from the constant-expression type.
18
19Pascal introduced the enumeration type characterized by a set of ordered, unscoped identifiers (enumerators), which are not overloadable.\footnote{%
20Pascal is \emph{case-insensitive} so identifiers may appear in multiple forms and still be the same, \eg \lstinline{Mon}, \lstinline{moN}, and \lstinline{MON} (a questionable design decision).}
21\begin{pascal}
22type Week = ( Mon, Tue, Wed, Thu, Fri, Sat, Sun );
23\end{pascal}
24Object initialization and assignment are restricted to the enumerators of this type.
25Enumerators are auto-initialized from left to right, starting at zero and incrementing by 1.
26Enumerators \emph{cannot} be explicitly initialized.
27Pascal provides a predefined type \lstinline[language=Pascal]{Boolean} defined as:
28\begin{pascal}
29type Boolean = ( false, true );
30\end{pascal}
31The enumeration supports the relational operators @=@, @<>@, @<@, @<=@, @>=@, and @>@, interpreted as as comparison in terms of declaration order.
32
33The following auto-generated pseudo-functions exist for all enumeration types:
34\begin{cquote}
35\begin{tabular}{@{}ll@{}}
36@succ( T )@     & @succ( Tue ) = Wed@ \\
37@pred( T )@     & @pred( Tue ) =  Mon@ \\
38@ord( T )@      & @ord( Tue ) = 1@
39\end{tabular}
40\end{cquote}
41
42Pascal provides \emph{consecutive} subsetting of an enumeration using a subrange type.
43\begin{pascal}
44type Week = ( Mon, Tue, Wed, Thu, Fri, Sat, Sun );
45           Weekday = @Mon..Fri@;   { subtype }
46           Weekend = @Sat..Sun@;
47var day : Week;
48         wday : Weekday;
49         wend : Weekend;
50\end{pascal}
51Hence, declaration order of enumerators is crucial to provide the necessary ranges.
52There is a bidirectional assignment between the enumeration and its subranges.
53\begin{pascal}
54day := Sat;
55@wday := day;@                  $\C[1.5in]{\{ check \}}$
56wend := day;                    $\C{\{ maybe check \}}$
57day := Mon;
58wday := day;                    $\C{\{ maybe check \}}$
59@wend := day;@                  $\C{\{ check \}}$
60day := wday;                    $\C{\{ no check \}}$
61day := wend;                    $\C{\{ no check \}}\CRT$
62\end{pascal}
63A static/dynamic range check should be performed to verify the values assigned to subtypes.
64(Free Pascal does not check and aborts in certain situations, like writing an invalid enumerator.)
65
66An enumeration can be used in the @if@ and @case@ statements or iterating constructs.
67\begin{cquote}
68\setlength{\tabcolsep}{15pt}
69\begin{tabular}{@{}ll@{}}
70\begin{pascal}
71day := Mon;
72if @day@ = wday then
73        Writeln( day );
74if @day@ <= Fri then
75        Writeln( 'weekday');
76Mon
77weekday
78\end{pascal}
79&
80\begin{pascal}
81
82case @day@ of
83  Mon..Fri :
84        Writeln( 'weekday');
85  Sat..Sun :
86        Writeln( 'weekend')
87end;
88weekday
89\end{pascal}
90\end{tabular}
91\end{cquote}
92\begin{cquote}
93\setlength{\tabcolsep}{15pt}
94\begin{tabular}{@{}ll@{}}
95\begin{pascal}
96while day <= Sun do begin
97        Write( day, ' ' );
98        day := succ( day );
99end;
100Mon Tue Wed Thu Fri Sat Sun
101\end{pascal}
102&
103\begin{pascal}
104for day := Mon to Sun do begin
105        Write( day, ' ' );
106
107end;
108Mon Tue Wed Thu Fri Sat Sun
109\end{pascal}
110\end{tabular}
111\end{cquote}
112Note that subtypes @Weekday@ and @Weekend@ cannot be used to define a case or loop range.
113
114An enumeration type can be used as an array dimension and subscript.
115\begin{pascal}
116Lunch : array( @Week@ ) of Time;
117for day in Week loop
118        Lunch( @day@ ) := ... ;       { set lunch time }
119end loop;
120\end{pascal}
121
122Free Pascal~\cite[\S~3.1.1]{FreePascal} is a modern, object-oriented version of Pascal, with a C-style enumeration type.
123Enumerators can be assigned explicit values assigned in ascending numerical order using a constant expression, and the range can be non-consecutive.
124\begin{pascal}
125type Count = ( Zero, One, Two, Ten = 10, Eleven );
126\end{pascal}
127Pseudo-functions @pred@ and @succ@ can only be used if the range is consecutive.
128Enumerating gives extraneous values.
129\begin{pascal}
130for cnt := Zero to Eleven do begin
131        Write( ord( cnt ), ' ' );
132end;
1330 1 2 @3 4 5 6 7 8 9@ 10 11
134\end{pascal}
135
136The underlying type is an implementation-defined integral type large enough to hold all enumerated values; it does not have to be the smallest possible type.
137The integral size can be explicitly specified using compiler directive \$@PACKENUM@~$N$, where $N$ is the number of bytes, \eg:
138\begin{pascal}
139Type @{$\color{red}\$$PACKENUM 1}@ SmallEnum = ( one, two, three );
140                @{$\color{red}\$$PACKENUM 4}@ LargeEnum = ( BigOne, BigTwo, BigThree );
141Var S : SmallEnum; { 1 byte }
142          L : LargeEnum; { 4 bytes}
143\end{pascal}
144
145
146\section{Ada}
147\label{s:Ada}
148
149An Ada enumeration type is a set of ordered, unscoped identifiers (enumerators) bound to \emph{unique} \newterm{literals}.\footnote{%
150Ada is \emph{case-insensitive} so identifiers may appear in multiple forms and still be the same, \eg \lstinline{Mon}, \lstinline{moN}, and \lstinline{MON} (a questionable design decision).}
151\begin{ada}
152type Week is ( Mon, Tue, Wed, Thu, Fri, Sat, Sun ); -- literals (enumerators)
153\end{ada}
154Object initialization and assignment are restricted to the enumerators of this type.
155While Ada enumerators are unscoped, like C, Ada enumerators are overloadable.
156\begin{ada}
157type RGB is ( @Red@, @Green@, Blue );
158type Traffic_Light is ( @Red@, Yellow, @Green@ );
159\end{ada}
160Like \CFA, Ada uses a type-resolution algorithm, including the left-hand side of the assignment, to disambiguate among overloaded identifiers.
161\VRef[Figure]{f:AdaEnumeration} shows how ambiguity is handled using a cast, \eg \lstinline[language=ada]{RGB'(Red)}.
162
163\begin{figure}
164\begin{ada}
165with Ada.Text_IO; use Ada.Text_IO;
166procedure test is
167        type RGB is ( @Red@, Green, Blue );
168        type Traffic_Light is ( @Red@, Yellow, Green );         -- overload
169        procedure @Red@( Colour : RGB ) is begin            -- overload
170                Put_Line( "Colour is " & RGB'Image( Colour ) );
171        end Red;
172        procedure @Red@( TL : Traffic_Light ) is begin       -- overload
173                Put_Line( "Light is " & Traffic_Light'Image( TL ) );
174        end Red;
175begin
176        @Red@( Blue );                           -- RGB
177        @Red@( Yellow );                                -- Traffic_Light
178        @Red@( @RGB'(Red)@ );           -- ambiguous without cast
179end test;
180\end{ada}
181\caption{Ada Enumeration Overload Resolution} 
182\label{f:AdaEnumeration}
183\end{figure}
184
185Enumerators without initialization are auto-initialized from left to right, starting at zero and incrementing by 1.
186Enumerators with initialization must set \emph{all} enumerators in \emph{ascending} order, \ie there is no auto-initialization.
187\begin{ada}
188type Week is ( Mon, Tue, Wed, Thu, Fri, Sat, Sun );
189        for Week use ( Mon => 0, Tue => 1, Wed => 2, Thu => @10@, Fri => 11, Sat => 14, Sun => 15 );
190\end{ada}
191The enumeration operators are the equality and relational operators, @=@, @/=@, @<@, @<=@, @=@, @/=@, @>=@, @>@, where the ordering relationship is given implicitly by the sequence of ascending enumerators.
192
193Ada provides an alias mechanism, \lstinline[language=ada]{renames}, for aliasing types, which is useful to shorten package identifiers.
194\begin{ada}
195@OtherRed@ : RGB renames Red;
196\end{ada}
197which suggests a possible \CFA extension to @typedef@.
198\begin{cfa}
199typedef RGB.Red OtherRed;
200\end{cfa}
201
202There are three pairs of inverse enumeration pseudo-functions (attributes): @'Pos@ and @'Val@, @'Enum_Rep@ and @'Enum_Val@, and @'Image@ and @'Value@,
203\begin{cquote}
204\setlength{\tabcolsep}{15pt}
205\begin{tabular}{@{}ll@{}}
206\begin{ada}
207RGB'Pos( Red ) = 0;
208RGB'Enum_Rep( Red ) = 10;
209RGB'Image( Red ) = "RED";
210\end{ada}
211&
212\begin{ada}
213RGB'Val( 0 ) = Red
214RGB'Enum_Val( 10 ) =  Red
215RGB'Value( "Red" ) =  Red
216\end{ada}
217\end{tabular}
218\end{cquote}
219These attributes are important for IO.
220An enumeration type @T@ also has the following attributes: @T'First@, @T'Last@, @T'Range@, @T'Pred@, @T'Succ@, @T'Min@, and @T'Max@, producing an intuitive result based on the attribute name.
221
222Ada allows the enumerator label to be a character constant.
223\begin{ada}
224type Operator is ( '+', '-', '*', '/' );
225\end{ada}
226which is syntactic sugar for the label and not character literals from the predefined type @Character@.
227The purpose is strictly readability using character literals rather than identifiers.
228\begin{ada}
229Op : Operator := '+';
230if Op = '+' or else Op = '-' then ... ;
231elsif Op = '*' or else Op = '/' then ... ; end if;
232\end{ada}
233Interestingly, arrays of character enumerators can be treated as strings.
234\begin{ada}
235Ops : array( 0..3 ) of Operator;
236Ops := @"+-*/"@;            -- string assignment to array elements
237Ops := "+-" @&@ "*/";   -- string concatenation and assignment
238\end{ada}
239Ada's @Character@ type is defined as a character enumeration across all Latin-1 characters.
240
241Ada's boolean type is also a special enumeration, which can be used in conditions.
242\begin{ada}
243type Boolean is (False, True); -- False / True not keywords
244@Flag@ : Boolean;
245if @Flag@ then ...    -- conditional
246\end{ada}
247Since only types derived from @Boolean@ can be conditional, @Boolean@ is essentially a builtin type.
248
249Ada provides \emph{consecutive} subsetting of an enumeration using \lstinline[language=ada]{range}.
250\begin{ada}
251type Week is ( Mon, Tue, Wed, Thu, Fri, Sat, Sun );
252subtype Weekday is Week @range Mon .. Fri@;
253subtype Weekend is Week @range Sat .. Sun@;
254Day : Week;
255\end{ada}
256Hence, the ordering of the enumerators is crucial to provide the necessary ranges.
257
258An enumeration type can be used in the Ada \lstinline[language=ada]{case} (all enumerators must appear or a @default@) or iterating constructs.
259\begin{cquote}
260\setlength{\tabcolsep}{15pt}
261\begin{tabular}{@{}ll@{}}
262\begin{ada}
263case Day is
264        when @Mon .. Fri@ => ... ;
265        when @Sat .. Sun@ => ... ;
266end case;
267\end{ada}
268&
269\begin{ada}
270case Day is
271        when @Weekday@ => ... ;  -- subtype ranges
272        when @Weekend@ => ... ;
273end case;
274\end{ada}
275\end{tabular}
276\end{cquote}
277
278\begin{cquote}
279\setlength{\tabcolsep}{12pt}
280\begin{tabular}{@{}lll@{}}
281\begin{ada}
282for Day in @Mon .. Sun@ loop
283        ...
284end loop;
285\end{ada}
286&
287\begin{ada}
288for Day in @Weekday@ loop
289        ...
290end loop;
291\end{ada}
292&
293\begin{ada}
294for Day in @Weekend@ loop
295        ...
296end loop;
297\end{ada}
298\end{tabular}
299\end{cquote}
300
301An enumeration type can be used as an array dimension and subscript.
302\begin{ada}
303Lunch : array( @Week@ ) of Time;
304for Day in Week loop
305        Lunch( @Day@ ) := ... ;       -- set lunch time
306end loop;
307\end{ada}
308
309
310\section{\CC}
311\label{s:C++RelatedWork}
312
313\CC enumeration is largely backward compatible with C, so it inherited C's enumerations with some modifications and additions.
314
315\CC has aliasing using @const@ declarations, like C \see{\VRef{s:Cconst}}, with type inferencing, plus static/dynamic initialization.
316(Note, a \CC @constexpr@ declaration is the same as @const@ with the restriction that the initialization is a compile-time expression.)
317\begin{c++}
318const @auto@ one = 0 + 1;                               $\C{// static initialization}$
319const @auto@ NIL = nullptr;
320const @auto@ PI = 3.14159;
321const @auto@ Plus = '+';
322const @auto@ Fred = "Fred";
323const @auto@ Mon = 0, Tue = Mon + 1, Wed = Tue + 1, Thu = Wed + 1, Fri = Thu + 1,
324                                Sat = Fri + 1, Sun = Sat + 1;
325void foo() {
326        const @auto@ r = random();                      $\C{// dynamic initialization}$
327        int va[r];                                                      $\C{// VLA, auto scope only}$
328}
329\end{c++}
330Statically initialized identifiers may appear in any constant-expression context, \eg @case@.
331Dynamically initialized identifiers may appear as array dimensions in @g++@, which allows variable-sized arrays.
332Interestingly, global \CC @const@ declarations are implicitly marked @static@ (@r@, read-only local, rather than @R@, read-only external)
333\begin{c++}
334$\$$ nm test.o
3350000000000000018 @r@ Mon
336\end{c++}
337whereas C @const@ declarations without @static@ are marked @R@.
338This difference results from linking concerns that come from templates.
339
340The following \CC non-backward compatible change is made, plus the safe-assignment change shown in~\VRef{s:TypeSafety}.
341\begin{cquote}
342\begin{description}[leftmargin=*,topsep=0pt,itemsep=0pt,parsep=0pt]
343\item[Change:] In \CC, the type of an enumerator is its enumeration.
344In C, the type of an enumerator is @int@.
345Example:
346\begin{c++}
347enum e { A };
348sizeof(A) == sizeof(int)                                $\C{// in C}$
349sizeof(A) == sizeof(e)                                  $\C{// in \CC}$
350/* and sizeof(int) is not necessary equal to sizeof(e) */
351\end{c++}
352\item[Rationale:] In \CC, an enumeration is a distinct type.
353\item[Effect on original feature:] Change to semantics of well-defined feature.
354\item[Difficulty of converting:] Semantic transformation.
355\item[How widely used:] Seldom. The only time this affects existing C code is when the size of an enumerator is taken.
356Taking the size of an enumerator is not a common C coding practice.
357\end{description}
358\hfill ISO/IEC 14882:1998 (\CC Programming Language Standard)~\cite[C.1.5.7.2.6]{ANSI98:C++}
359\end{cquote}
360Hence, the values in a \CC enumeration can only be its enumerators (without a cast).
361
362While the storage size of an enumerator is up to the compiler, there is still an implicit cast to @int@.
363\begin{c++}
364enum E { A, B, C };
365E e = A;
366int i = A;    i = e;                                    $\C{// implicit casts to int}$
367\end{c++}
368\CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct})\footnote{
369The use of keyword \lstinline[language=c++]{class} is reasonable because default visibility is \lstinline[language=c++]{private} (scoped).
370However, default visibility for \lstinline[language=c++]{struct} is \lstinline[language=c++]{public} (unscoped) making it an odd choice.},
371where the enumerators are accessed using type qualification.
372\begin{c++}
373enum class E { A, B, C };
374E e = @E::@A;                                                   $\C{// qualified enumerator}$
375e = B;                                                                  $\C{// error: B not in scope}$
376\end{c++}
377\CC{20} supports explicit unscoping with a \lstinline[language=c++]{using enum} declaration.
378\begin{c++}
379enum class E { A, B, C };
380@using enum E;@
381E e = A;    e = B;                                              $\C{// direct access}$
382\end{c++}
383\CC{11} added the ability to explicitly declare an underlying \emph{integral} type for \lstinline[language=c++]{enum class}.
384\begin{c++}
385enum class RGB @: long@ { Red, Green, Blue };
386enum class rgb @: char@ { Red = 'r', Green = 'g', Blue = 'b' };
387enum class srgb @: signed char@ { Red = -1, Green = 0, Blue = 1 };
388\end{c++}
389There is no implicit conversion from the \lstinline[language=c++]{enum class} type to its declared type.
390\begin{c++}
391rgb crgb = rgb::Red;
392char ch = rgb::Red;   ch = crgb;                $\C{// error}$
393\end{c++}
394An enumeration can be used in the @if@ and @switch@ statements.
395\begin{cquote}
396\setlength{\tabcolsep}{15pt}
397\begin{tabular}{@{}ll@{}}
398\begin{c++}
399if ( @day@ <= Fri )
400        cout << "weekday" << endl;
401
402
403
404
405\end{c++}
406&
407\begin{c++}
408switch ( @day@ ) {
409  case Mon: case Tue: case Wed: case Thu: case Fri:
410        cout << "weekday" << endl; break;
411  case Sat: case Sun:
412        cout << "weekend" << endl; break;
413}
414\end{c++}
415\end{tabular}
416\end{cquote}
417However, there is no mechanism to iterate through an enumeration.
418A common workaround is to iterate over enumerator as integral values, but it only works if
419enumerators resemble a sequence of natural, i.e., enumerators are auto-initialized.
420Otherwise, the iteration would have integers that are not enumeration values.
421\begin{c++}
422enum Week { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun };
423for ( Week d = Mon; d <= Sun; d = @(Week)(d + 1)@ ) cout << d << ' ';
4240 1 2 @3 4 5 6 7 8 9@ 10 11 12 13
425\end{c++}
426As a consequence, there is no meaningful enumerating mechanism.
427
428An enumeration type cannot declare an array dimension but an enumerator can be used as a subscript.
429There is no mechanism to subset or inherit from an enumeration.
430
431
432\section{C\texorpdfstring{\raisebox{-0.7ex}{\LARGE$^\sharp$}\xspace}{Csharp}} % latex bug: cannot use \relsize{2} so use \LARGE
433\label{s:Csharp}
434
435% https://www.tutorialsteacher.com/codeeditor?cid=cs-mk8Ojx
436% https://learn.microsoft.com/en-us/dotnet/api/system.enum?view=net-8.0
437% https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/enums
438
439\Csharp is a programming language with a scoped, integral enumeration similar to \CC \lstinline[language=C++]{enum class}.
440\begin{csharp}
441enum Week : @long@ { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun }
442enum RGB { Red, Green, Blue }
443\end{csharp}
444The default underlying integral type is @int@, with auto-incrementing and implicit/explicit initialization.
445A method cannot be defined in an enumeration type (extension methods are possible).
446There is an explicit bidirectional conversion between an enumeration and its integral type, and an implicit conversion to the enumerator label in display contexts.
447\begin{csharp}
448int iday = (int)Week.Fri;                       $\C{// day == 11}$
449Week day = @(Week)@42;                          $\C{// day == 42, unsafe}$
450string mon = Week.Mon.ToString();       $\C{// mon == "Mon"}$
451RGB rgb = RGB.Red;                                      $\C{// rgb == "Red"}$
452day = @(Week)@rgb;                                      $\C{// day == "Mon", unsafe}$
453Console.WriteLine( Week.Fri );          $\C{// print label Fri}$
454\end{csharp}
455% The majority of the integral operators (relational and arithmetic) work with enumerations, except @*@ and @/@.
456% Relational and arithmetic operators are defined in terms of its numeric value only.
457% Therefore, enumerators are not ordered and not enumerable like \CC.
458Like \CC, \Csharp defines enumeration relational and arithmetic operators in terms of value.
459Enumerators have no defined positional meaning.
460\begin{csharp}
461day = day++ - 5;                                        $\C{// value manipulation}$
462day = day & day;
463\end{csharp}
464\begin{csharp}
465for ( Week d = Mon; d <= Sun; @d += 1@ ) {
466        Console.Write( d + " " );
467}
468Mon Tue Wed @3 4 5 6 7 8 9@ Thu Fri Sat Sun
469\end{csharp}
470As a consequence, there is no direct meaningful enumerating mechanism.
471
472An enumeration can be used in the @if@ and @switch@ statements.
473\begin{cquote}
474\setlength{\tabcolsep}{15pt}
475\begin{tabular}{@{}ll@{}}
476\begin{csharp}
477if ( @day@ <= Week.Fri )
478        Console.WriteLine( "weekday" );
479
480
481
482
483
484\end{csharp}
485&
486\begin{csharp}
487switch ( @day@ ) {
488  case Week.Mon: case Week.Tue: case Week.Wed:
489  case Week.Thu: case Week.Fri:
490        Console.WriteLine( "weekday" ); break;
491  case Week.Sat: case Week.Sun:
492        Console.WriteLine( "weekend" ); break;
493}
494\end{csharp}
495\end{tabular}
496\end{cquote}
497
498To indirectly enumerate, \Csharp's Enum library provides @Enum.GetValues@,
499% a pseudo-method that retrieves an array of the enumeration constants for looping over an enumeration type or variable (expensive operation).
500a static member of abstract Enum type that return a reference to an array of all enumeration constants.
501Internally, a Enum type has a static member called @fieldInfoHash@ -- a @Hashtable@ that stores enumerators information.
502The field is populated on-demand: it only contains information if a @reflection@ like @GetValues@ is called.
503As an optimization, this information is cached, so the cost of reflection is paid once throughout the lifetime of a program.
504@GetValues@ then converts a @Hashtable@ to an @Array@, which supports enumerating.
505\begin{csharp}
506foreach ( Week d in @Enum.GetValues@( typeof(Week) ) ) {
507        Console.WriteLine( d + " " + (int)d + " " ); // label, position
508}
509Mon 0, Tue 1, Wed 2, Thu 10, Fri 11, Sat 12, Sun 13,
510\end{csharp}
511Hence, enumerating is not supplied directly by the enumeration, but indirectly through the expensive $O(N)$ creation of an enumerable array type, and recreating this array for each enumerating, versus direct arithmetic.
512
513An enumeration type cannot declare an array dimension but an enumerator can be used as a subscript.
514There is no mechanism to subset or inherit from an enumeration.
515
516The @Flags@ attribute creates a bit-flags enumeration, making bitwise operators @&@, @|@, @~@ (complement), @^@ (xor) sensible.
517\begin{csharp}
518@[Flags]@ public enum Week {
519        None = 0x0, Mon = 0x1, Tue = 0x2, Wed = 0x4,
520        Thu = 0x8, Fri = 0x10, Sat = 0x20, Sun = 0x40,
521        Weekdays = @Mon | Tue | Wed | Thu | Fri@ $\C{// Weekdays == 0x1f}$
522        Weekend = @Sat | Sun@,                  $\C{// Weekend == 0x60}$
523}
524Week meetings = @Week.Mon | Week.Wed@; $\C{// 0x5}$
525\end{csharp}
526
527
528\section{Go}
529\label{s:Go}
530
531Go has @const@ aliasing declarations, similar to \CC \see{\VRef{s:C++RelatedWork}}, for basic types with type inferencing and static initialization (constant expression).
532The most basic form of constant definition is a @const@ keyword, followed by the name of constant, an optional type declaration of the constant, and a mandatory initialize.
533For example:
534\begin{Go}
535const R @int@ = 0;  const G @uint@ = 1;  const B = 2; $\C{// explicit typing and type inferencing}$
536const Fred = "Fred";  const Mary = "Mary";  const Jane = "Jane";
537const S = 0;  const T = 0;
538const USA = "USA";  const U = "USA";
539const V = 3.1;  const W = 3.1;
540\end{Go}
541Since these declarations are immutable variables, they are unscoped and Go has no overloading. If no type declaration provided, Go infers
542type from the initializer expression.
543
544% Go provides an enumeration-like feature to group together @const@ declaration into a block and introduces a form of auto-initialization.
545These named constants can be grouped together in one @const@ declaration block to introduce a form of auto-initialization.
546\begin{Go}
547const ( R = 0; G; B )                                   $\C{// implicit initialization: 0 0 0}$
548const ( Fred = "Fred"; Mary = "Mary"; Jane = "Jane" ) $\C{// explicit initialization: Fred Mary Jane}$
549const ( S = 0; T; USA = "USA"; U; V = 3.1; W ) $\C{// implicit/explicit: 0 0 USA USA 3.1 3.1}$
550\end{Go}
551The first identifier \emph{must} be explicitly initialized;
552subsequent identifiers can be implicitly or explicitly initialized.
553Implicit initialization always uses the \emph{previous} (predecessor) constant expression initializer.
554A constant block can still use explicit declarations, and following constants inherit that type.
555\begin{Go}
556type BigInt int64
557const ( R @BigInt@ = 0; G; B )
558const ( Fred @string@ = "Fred"; Mary = "Mary"; Jane = "Jane" )
559const ( S @int@ = 0; T; USA @string@ = "USA"; U; V @float32@ = 3.1; W )
560\end{Go}
561Typing the first constant and implicit initializing is still not a enumeration because there is no unique type for the constant block;
562nothing stops other constant blocks from having the same type.
563
564Each @const@ declaration provides an implicit \emph{compile-time} integer counter starting at @0@, called \lstinline[language=Go]{iota}, which is post-incremented after each constant declaration.
565% Each @const@ declaration is often paired with a const expression \lstinline[language=Go]{iota} to re-define its implicit initialization.
566% \lstinline[language=Go]{iota} represents a sequence of natural numbers starting from zero.
567% Using \lstinline[language=Go]{iota} outside of a @const@ block always sets the identifier to zero.
568% \begin{Go}
569% const R = iota;                                                       $\C{// 0}$
570% \end{Go}
571% Inside a @const@ block, \lstinline[language=Go]{iota} is implicitly incremented for each \lstinline[language=golang]{const} identifier and used to initialize the next uninitialized identifier.
572% Inside a @const@ block, if a constant has \lstinline[language=Go]{iota} initializer, its successor will also use \lstinline[language=Go]{iota} initializer.
573% Inside a @const@ block, if a constant has \lstinline[language=Go]{iota} initializer, its successor will also use \lstinline[language=Go]{iota} initializer.
574% \lstinline[language=Go]{iota} is no different than other constant expression when it is used in implicit initialization, but thanks to the increment natural of \lstinline[language=Go]{iota}, the successor will have a value equal to its predecessor plus 1.
575\begin{Go}
576const ( R = @iota@; G; B )                                      $\C{// implicit: 0 1 2}$
577const ( C = @iota + B + 1@; G; Y )                      $\C{// implicit: 3 4 5}$
578\end{Go}
579which are equivalent to:
580\begin{Go}
581const ( R = @iota@; G = @iota@; B = @iota@ ) $\C{// implicit: 0 1 2}$
582const ( C = @iota + B + 1@; G = @iota + B + 1@; Y = @iota + B + 1@ ) $\C{// implicit: 3 4 5}$
583\end{Go}
584An underscore \lstinline[language=golang]{const} identifier advances \lstinline[language=Go]{iota}.
585\begin{Go}
586const ( O1 = iota + 1; @_@; O3; @_@; O5 )       $\C{// 1, 3, 5}$
587\end{Go}
588Auto-initialization reverts from \lstinline[language=Go]{iota} to the previous value after an explicit initialization, but auto-incrementing of \lstinline[language=Go]{iota} continues.
589\begin{Go}
590const ( Mon = iota; Tue; Wed;                           $\C{// 0, 1, 2}$
591                 @Thu = 10@; Fri; Sat; @Sun = iota@ ) $\C{// 10, 10, 10, {\color{red}6}}$
592\end{Go}
593Auto-initialization from \lstinline[language=Go]{iota} is restarted and \lstinline[language=Go]{iota} reinitialized with an expression containing at most \emph{one} \lstinline[language=Go]{iota}.
594\begin{Go}
595const ( V1 = iota; V2; @V3 = 7;@ V4 = @iota@ + 1; V5 ) // 0 1 7 4 5
596const ( Mon = iota; Tue; Wed; // 0, 1, 2
597                @Thu = 10;@ Fri = @iota@ - Wed + Thu - 1; Sat; Sun ) // 10, 11, 12, 13
598\end{Go}
599Here, @V4@ and @Fri@ restart auto-incrementing from \lstinline[language=Go]{iota} and reset \lstinline[language=Go]{iota} to 4 and 11, respectively, because of the initialization expressions containing \lstinline[language=Go]{iota}.
600Note, because \lstinline[language=Go]{iota} is incremented for an explicitly initialized identifier or @_@,
601at @Fri@ \lstinline[language=Go]{iota} is 4 requiring the minus one to compute the value for @Fri@.
602
603Basic switch and looping are possible.
604\begin{cquote}
605\setlength{\tabcolsep}{20pt}
606\begin{tabular}{@{}ll@{}}
607\begin{Go}
608day := Mon;     // := $\(\Rightarrow\)$ type inferencing
609switch @day@ {
610  case Mon, Tue, Wed, Thu, Fri:
611        fmt.Println( "weekday" );
612  case Sat, Sun:
613        fmt.Println( "weekend" );
614}
615\end{Go}
616&
617\begin{Go}
618
619for i := @Mon@; i <= @Sun@; i += 1 {
620        fmt.Println( i )
621}
622
623
624
625\end{Go}
626\end{tabular}
627\end{cquote}
628However, the loop in this example prints the values from 0 to 13 because there is no actual enumeration.
629
630A constant variable can be used as an array dimension or a subscript.
631\begin{Go}
632var ar[@Sun@] int
633ar[@Mon@] = 3
634\end{Go}
635
636
637\section{Java}
638
639Java provides an enumeration using a specialized class.
640A basic Java enumeration is an opaque enumeration, where the enumerators are constants.
641\begin{Java}
642enum Week { Mon, Tue, Wed, Thu, Fri, Sat, Sun; }
643Week day = Week.Sat;
644\end{Java}
645The enumerator's members are scoped requiring qualification.
646The value of an enumeration instance is restricted to its enumerators.
647
648The position (ordinal) and label (name) are accessible but there is no value property.
649\begin{Java}
650System.out.println( day.!ordinal()! + " " + !day! + " " + day.!name()! );
6515 Sat Sat
652\end{Java}
653Since @day@ has no value, it prints its label (name).
654The member @valueOf@ is the inverse of @name@ converting a string to an enumerator.
655\begin{Java}
656day = Week.valueOf( "Wed" );
657\end{Java}
658Extra members can be added to provide specialized operations.
659\begin{Java}
660public boolean isWeekday() { return !ordinal()! <= Fri.ordinal(); }
661public boolean isWeekend() { return Sat.ordinal() <= !ordinal()!; }
662\end{Java}
663Notice the unqualified calls to @ordinal@ in the members implying a \lstinline[language=Java]{this} to some implicit implementation variable, likely an @int@.
664
665Enumerator values require an enumeration type (any Java type may be used) and implementation member.
666\begin{Java}
667enum Week {
668        Mon!(1)!, Tue!(2)!, Wed!(3)!, Thu!(4)!, Fri!(5)!, Sat!(6)!, Sun!(7)!; // must appear first
669        private !long! day;                                     $\C{// enumeration type and implementation member}$
670        private Week( !long! d ) { day = d; } $\C{// enumerator initialization}$
671};
672Week day = Week.Sat;
673\end{Java}
674The position, value, and label are accessible.
675\begin{Java}
676System.out.println( !day.ordinal()! + " " + !day.day! + " " + !day.name()! );
6775 6 Sat
678\end{Java}
679If the implementation member is \lstinline[language=Java]{public}, the enumeration is unsafe, as any value of the underlying type can be assigned to it, \eg @day = 42@.
680The implementation constructor must be private since it is only used internally to initialize the enumerators.
681Initialization occurs at the enumeration-type declaration.
682
683Enumerations can be used in the @if@ and @switch@ statements but only for equality tests.
684\begin{cquote}
685\setlength{\tabcolsep}{15pt}
686\begin{tabular}{@{}ll@{}}
687\begin{Java}
688if ( !day! == Week.Fri )
689        System.out.println( "Fri" );
690
691
692
693
694\end{Java}
695&
696\begin{Java}
697switch ( !day! ) {
698  case Mon: case Tue: case Wed: case Thu: case Fri:
699        System.out.println( "weekday" );  break;
700  case Sat: case Sun:
701        System.out.println( "weekend" );  break;
702}
703\end{Java}
704\end{tabular}
705\end{cquote}
706Notice enumerators in the @switch@ statement do not require qualification.
707
708There are no arithmetic operations on enumerations, so there is no arithmetic way to iterate through an enumeration without making the implementation type \lstinline[language=Java]{public}.
709Like \Csharp, enumerating is supplied indirectly through another enumerable type, not via the enumeration.
710Specifically, Java supplies a static method @values@, which returns an array of enumerator values.
711Unfortunately, @values@ is an expensive @O(n)@ operation, which is recreated each time it is called.
712\begin{Java}
713for ( Week d : Week.values() ) {
714        System.out.print( d.ordinal() + d.day + " " +  d.name() + ",  " );
715}
7160 1 Mon,  1 2 Tue,  2 3 Wed,  3 4 Thu,  4 5 Fri,  5 6 Sat,  6 7 Sun, 
717\end{Java}
718
719% Java provides an @EnumSet@ where the underlying type is an efficient set of bits, one per enumeration \see{\Csharp \lstinline{Flags}, \VRef{s:Csharp}}, providing (logical) operations on groups of enumerators.
720% There is also a specialized version of @HashMap@ with enumerator keys, which has performance benefits.
721Java provides @EnumSet@, an auxiliary data structure that takes an enum @class@ as parameter (Week.class) for its construction, and it contains members only with the supplied enum type.
722@EnumSet@ is enumerable because it extends @AbstractSet@ interfaces and thus supports direct enumerating via @forEach@.
723It also has subset operation @range@ and it is possible to add to and remove from members of the set.
724@EnumSet@ supports more enumeration features, but it is not an enumeration type: it is a set of enumerators from a pre-define enum.
725
726An enumeration type cannot declare an array dimension nor can an enumerator be used as a subscript.
727Enumeration inheritence is disallowed because an enumeration is \lstinline[language=Java]{final}.
728
729
730\section{Rust}
731
732% https://doc.rust-lang.org/reference/items/enumerations.html
733
734Rust @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration.
735When @enum@ is an ADT, pattern matching is used to discriminate among the variant types.
736\begin{cquote}
737\begin{tabular}{@{}l@{\hspace{30pt}}ll@{}}
738\begin{rust}
739struct S {
740        i : isize,  j : isize
741}
742let mut s = S{ i : 3, j : 4 };
743enum @ADT@ {
744        I( isize ), $\C[1in]{// int}$
745        F( f64 ),   $\C{// float}$
746        S( S ),     $\C{// struct}\CRT$
747}
748\end{rust}
749&
750\begin{rust}
751let mut adt : ADT;
752adt = ADT::I(3);  println!( "{:?}", adt );
753adt = ADT::F(3.5);  println!( "{:?}", adt );
754adt = ADT::S(s);  println!( "{:?}", adt );
755@match@ adt {
756        ADT::I( i ) $=>$ println!( "{:}", i ),
757        ADT::F( f ) $=>$ println!( "{:}", f ),
758        ADT::S( s ) $=>$ println!( "{:} {:}", s.i, s.j ),
759}
760\end{rust}
761&
762\begin{rust}
763I(3)
764F(3.5)
765S(S { i: 3, j: 4 })
7663 4
767
768
769
770
771
772\end{rust}
773\end{tabular}
774\end{cquote}
775Even when the variant types are the unit type, the ADT is still not an enumeration because there is no enumerating \see{\VRef{s:AlgebraicDataType}}.
776\begin{rust}
777enum Week { Mon, Tues, Wed, Thu, Fri, Sat, Sun@,@ } // terminating comma
778let mut week : Week = Week::Mon;
779match week {
780        Week::Mon $=>$ println!( "Mon" ),
781        ...
782        Week::Sun $=>$ println!( "Sun" ),
783}
784\end{rust}
785
786However, Rust allows direct setting of the ADT constructor, which means it is actually a tag.
787\begin{cquote}
788\setlength{\tabcolsep}{15pt}
789\begin{tabular}{@{}ll@{}}
790\begin{rust}
791enum Week {
792        Mon, Tues, Wed, // start 0
793        Thu @= 10@, Fri,
794        Sat, Sun,
795}
796
797\end{rust}
798&
799\begin{rust}
800#[repr(u8)]
801enum ADT {
802        I(isize) @= 5@,
803        F(f64) @= 10@,
804        S(S) @= 0@,
805}
806\end{rust}
807\end{tabular}
808\end{cquote}
809Through this integral tag, it is possible to enumerate, and when all tags represent the unit type, it behaves like \CC \lstinline[language=C++]{enum class}.
810When tags represent non-unit types, Rust largely precludes accessing the tag because the semantics become meaningless.
811Hence, the two mechanisms are largely disjoint, and only the enumeration component is discussed.
812
813In detail, the @enum@ type has an implicit integer tag (discriminant) with a unique value for each variant type.
814Direct initialization is achieved by a compile-time expression that generates a constant value.
815Indirect initialization (without initialization, @Fri@/@Sun@) is auto-initialized: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@.
816There is an explicit cast from the tag to integer.
817\begin{rust}
818let mut mon : isize = Week::Mon as isize;
819\end{rust}
820An enumeration can be used in the @if@ and \lstinline[language=rust]{match} (@switch@) statements.
821\begin{cquote}
822\setlength{\tabcolsep}{8pt}
823\begin{tabular}{@{}ll@{}}
824\begin{c++}
825if @week as isize@ == Week::Mon as isize {
826        println!( "{:?}", week );
827}
828
829
830\end{c++}
831&
832\begin{c++}
833match @week@ {
834        Week::Mon | Week:: Tue | Week::Wed | Week::Thu
835                | Week::Fri => println!( "weekday" ),
836        Week::Sat | Week:: Sun $=>$ println!( "weekend" ),
837}
838\end{c++}
839\end{tabular}
840\end{cquote}
841% However, there is no mechanism to iterate through an enumeration without casting to integral and positions versus values is not handled.
842Like C/\CC, there is no mechanism to iterate through an enumeration.
843It can only be approximated by a loop over a range of enumerator and only works if the enumerator values are a sequence of natural numbers.
844\begin{c++}
845for d in Week::Mon as isize ..= Week::Sun as isize {
846        print!( "{:?} ", d );
847}
8480 1 2 @3 4 5 6 7 8 9@ 10 11 12 13
849\end{c++}
850% An enumeration type cannot declare an array dimension nor as a subscript.
851There is no direct way to harmonize an enumeration and another data structure.
852For example, there is no mapping from an enumerated type to an array type.
853In terms of extensibility, there is no mechanism to subset or inherit from an enumeration.
854
855
856\section{Swift}
857\label{s:Swift}
858% https://www.programiz.com/swift/online-compiler
859Despite being named as enumeration, a Swift @enum@ is in fact a ADT: cases (enumerators) of an @enum@ can have heterogeneous types and be recursive.
860% Like Rust, Swift @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration.
861When @enum@ is an ADT, pattern matching is used to discriminate among the variant types.
862\begin{cquote}
863\setlength{\tabcolsep}{20pt}
864\begin{tabular}{@{}l@{\hspace{55pt}}ll@{}}
865\begin{swift}
866struct S {
867        var i : Int,  j : Int
868}
869var s = S( i : 3, j : 5 )
870@enum@ ADT {
871        case I(Int)   $\C[1.125in]{// int}$
872        case F(Float) $\C{// float}$
873        case S(S)     $\C{// struct}\CRT$
874}
875\end{swift}
876&
877\begin{swift}
878var adt : ADT
879adt = .I( 3 );  print( adt )
880adt = .F( 3.5 );  print( adt )
881adt = .S( s );  print( adt )
882@switch@ adt {  // pattern matching
883        case .I(let i):  print( i )
884        case .F(let f):  print( f )
885        case .S(let s):  print( s.i, s.j )
886}
887\end{swift}
888&
889\begin{swift}
890I(3)
891F(3.5)
892S(S(i: 3, j: 5))
8933 5
894
895
896
897
898
899\end{swift}
900\end{tabular}
901\end{cquote}
902Note, after an @adt@'s type is known, the enumerator is inferred without qualification, \eg @.I(3)@.
903% Normally an enumeration case needs a type qualification.
904%However, when pattern matching @adt@ of type @ADT@, the @case@ context provides the type @ADT@ so no explicit type qualification is required.
905
906% An enumeration is created when \emph{all} the enumerators are unit-type, which is like a scoped, opaque enumeration.
907Without type declaration for enumeration cases, the enumerators have unit-type, which is like a scoped, opaque enumeration.
908\begin{swift}
909enum Week { case Mon, Tue, Wed, Thu, Fri, Sat, Sun }; // unit-type
910var week : Week = @Week.Mon@;
911\end{swift}
912% As well, it is possible to type \emph{all} the enumerators with a common type, and set different values for each enumerator;
913% for integral types, there is auto-incrementing.
914As well, it is possible to type associated values of enumeration cases with a common type.
915When enumeration cases are typed with a common integral type, Swift auto-initialize enumeration cases following the same initialization scheme as C language.
916If an enumeration is typed with @string@, its cases are auto-initialized to case names (labels).
917\begin{cquote}
918\setlength{\tabcolsep}{15pt}
919\begin{tabular}{@{}lll@{}}
920\begin{swift}
921enum WeekInt: @Int@ {
922        case Mon, Tue, Wed, Thu = 10, Fri,
923                        Sat = 4, Sun // auto-incrementing
924};
925\end{swift}
926&
927\begin{swift}
928enum WeekStr: @String@ {
929        case Mon = "MON", Tue, Wed, Thu, Fri,
930                        Sat = "SAT", Sun
931};
932\end{swift}
933\end{tabular}
934\end{cquote}
935An enumeration only supports equality comparison between enumerator values, unless it inherits from @Comparable@, adding relational operators @<@, @<=@, @>@, and @>=@.
936
937An enumeration can have methods.
938\begin{swift}
939enum Week: @Comparable@ {
940        case Mon, Tue, Wed, Thu, Fri, Sat, Sun // unit-type
941        func @isWeekday() -> Bool@ { return self <= .Fri }  // methods
942        func @isWeekend() -> Bool@ { return .Sat <= self }
943};
944\end{swift}
945An enumeration can be used in the @if@ and @switch@ statements, where @switch@ must be exhaustive or have a @default@.
946\begin{cquote}
947\setlength{\tabcolsep}{15pt}
948\begin{tabular}{@{}ll@{}}
949\begin{swift}
950if @week <= .Fri@ {
951        print( "weekday" );
952}
953
954
955\end{swift}
956&
957\begin{swift}
958switch @week@ {
959        case .Mon: print( "Mon" )
960        ...
961        case .Sun: print( "Sun" )
962}
963\end{swift}
964\end{tabular}
965\end{cquote}
966Enumerating is accomplished by inheriting from @CaseIterable@ protocol, which has a static @enum.@ @allCases@ property that returns a collection of all the cases for looping over an enumeration type or variable.
967Like \CFA, Swift's default enumerator output is the case name (label). An enumerator of a typed enumeration has attribute
968@rawValue@ that return its case value.
969\begin{swift}
970enum Week: Comparable, @CaseIterable@ {
971        case Mon, Tue, Wed, Thu, Fri, Sat, Sun // unit-type
972};
973for day in Week@.allCases@ {
974        print( day, terminator:" " ) 
975}
976Mon Tue Wed Thu Fri Sat Sun
977\end{swift}
978
979
980\begin{cquote}
981\setlength{\tabcolsep}{15pt}
982\begin{tabular}{@{}lll@{}}
983\begin{swift}
984enum WeekInt: @Int@, CaseIterable {
985        case Mon, Tue, Wed, Thu = 10, Fri,
986                        Sat = 4, Sun // auto-incrementing
987};
988for day in WeekInt.allCases {
989        print( day@.rawValue@, terminator:" " ) 
990}
9910 1 2 10 11 4 5 
992\end{swift}
993&
994\begin{swift}
995enum WeekStr: @String@, CaseIterable {
996        case Mon = "MON", Tue, Wed, Thu, Fri,
997                        Sat = "SAT", Sun
998};
999for day in WeekStr.allCases {
1000        print( day@.rawValue@, terminator:" " ) 
1001}
1002MON Tue Wed Thu Fri SAT Sun
1003\end{swift}
1004\end{tabular}
1005\end{cquote}
1006
1007There is a safe bidirectional conversion from typed enumerator to @rawValue@ and vice versa.
1008\begin{swift}
1009if let opt = WeekInt( rawValue: 0 ) {  // test optional return value
1010        print( opt.rawValue, opt )  // 0 Mon
1011} else {
1012        print( "invalid weekday lookup" )
1013}
1014\end{swift}
1015% Conversion from @rawValue@ to enumerator may fail (bad lookup), so the result is an optional value.
1016In the previous example, the initialization of @opt@ fails if there is no enumeration value equal to 0, resulting in a @nil@ value.
1017Initialization from a raw value is considered a expensive operation because it requires a value lookup.
1018
1019
1020\section{Python 3.13}
1021% https://docs.python.org/3/howto/enum.html
1022
1023Python is a dynamically-typed reflexive programming language with multiple incompatible versions.
1024The generality of the language makes it possible to extend existing or build new language features.
1025As a result, discussing Python enumerations is a moving target, because if a feature does not exist, it can often be created with varying levels of complexity within the language.
1026Therefore, the following discussion is (mostly) restricted to the core enumeration features in Python 3.13.
1027
1028A Python enumeration is not a basic type;
1029it is a @class@ inheriting from the @Enum@ class.
1030The @Enum@ class presents a set of scoped enumerators, where each enumerator is a pair object with a \emph{constant} string name and an arbitrary value.
1031Hence, an enumeration instance is a fixed type (enumeration pair), and its value is the type of one of the enumerator pairs.
1032
1033The enumerator value fields must be explicitly initialized and be \emph{unique}.
1034\begin{python}
1035class Week(!Enum!): Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7
1036\end{python}
1037and/or explicitly auto-initialized with @auto@ method, \eg:
1038\begin{python}
1039class Week(Enum): Mon = 1; Tue = 2; Wed = 3; Thu = 10; Fri = !auto()!; Sat = 4; Sun = !auto()!
1040Mon : 1 Tue : 2 Wed : 3 Thu : 10 Fri : !11! Sat : 4 Sun : !12!
1041\end{python}
1042@auto@ is controlled by member @_generate_next_value_()@, which by default return one plus the highest value among enumerators, and can be overridden:
1043\begin{python}
1044@staticmethod
1045def _generate_next_value_( name, start, count, last_values ):
1046        return name
1047\end{python}
1048
1049There is no direct concept of restricting the enumerators in an enumeration \emph{instance} because dynamic typing changes the type.
1050\begin{python}
1051class RGB(Enum): Red = 1; Green = 2; Blue = 3
1052day : Week = Week.Tue;          $\C{\# type is Week}$
1053!day = RGB.Red!                         $\C{\# type is RGB}$
1054!day : Week = RGB.Red!          $\C{\# type is RGB}$
1055\end{python}
1056The enumerators are constants and cannot be reassigned.
1057Hence, while enumerators can be different types,
1058\begin{python}
1059class Diff(Enum): Int = 1; Float = 3.5; Str = "ABC"
1060\end{python}
1061it is not an ADT because the enumerator names are not constructors.
1062
1063An enumerator initialized with the same value is an alias and invisible at the enumeration level, \ie the alias is substituted for its aliasee.
1064\begin{python}
1065class WeekD(Enum): Mon = 1; Tue = 2; Wed = 3; Thu = !10!; Fri = !10!; Sat = !10!; Sun = !10!
1066\end{python}
1067Here, the enumeration has only 4 enumerators and 3 aliases.
1068An alias is only visible by dropping down to the @class@ level and asking for class members.
1069Aliasing is prevented using the @unique@ decorator.
1070\begin{python}
1071!@unique!
1072class DupVal(Enum): One = 1; Two = 2; Three = !3!; Four = !3!
1073ValueError: duplicate values found in <enum 'DupVal'>: Four -> Three
1074\end{python}
1075
1076\begin{lrbox}{\myboxA}
1077\begin{python}
1078def by_position(enum_type, position):
1079        for index, value in enumerate(enum_type):
1080                if position == index: return value
1081        raise Exception("by_position out of range")
1082\end{python}
1083\end{lrbox}
1084There are bidirectional enumeration pseudo-functions for label and value, but there is no concept of access using ordering (position).\footnote{
1085There is an $O(N)$ mechanism to access an enumerator's value by position. \newline \usebox\myboxA}
1086\begin{cquote}
1087\setlength{\tabcolsep}{15pt}
1088\begin{tabular}{@{}ll@{}}
1089\begin{python}
1090Week.Thu.value == 4;
1091Week.Thu.name == "Thu";
1092\end{python}
1093&
1094\begin{python}
1095Week( 4 ) == Week.Thu
1096Week["Thu"].value == 4
1097\end{python}
1098\end{tabular}
1099\end{cquote}
1100@Enum@ only supports equality comparison between enumerator values.
1101There are multiple library extensions to @Enum@, \eg @OrderedEnum@ recipe class, adding relational operators @<@, @<=@, @>@, and @>=@.
1102
1103An enumeration \lstinline[language=python]{class} can have methods.
1104\begin{python}
1105class Week(!OrderedEnum!):
1106        Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7
1107        def !isWeekday(self)!:          # methods
1108                return Week(self.value) !<=! Week.Fri
1109        def !isWeekend(self)!:
1110                return Week.Sat !<=! Week(self.value) 
1111\end{python}
1112
1113An enumeration can be used in the @if@ and @switch@ statements but only for equality tests, unless extended to @OrderedEnum@.
1114\begin{cquote}
1115\setlength{\tabcolsep}{12pt}
1116\begin{tabular}{@{}ll@{}}
1117\begin{python}
1118if day <= Week.Fri :
1119        print( "weekday" );
1120
1121
1122
1123\end{python}
1124&
1125\begin{python}
1126match day:
1127        case Week.Mon | Week.Tue | Week.Wed | Week.Thu | Week.Fri:
1128                print( "weekday" );
1129        case Week.Sat | Week.Sun:
1130                print( "weekend" );
1131\end{python}
1132\end{tabular}
1133\end{cquote}
1134Looping is performed using the enumeration type or @islice@ from @itertools@ based on position.
1135\begin{python}
1136for day in !Week!:                                      $\C[2.25in]{\# Mon : 1 Tue : 2 Wed : 3 Thu : 4 Fri : 5 Sat : 6 Sun : 7}$
1137        print( day.name, ":", day.value, end=" " )
1138for day in !islice(Week, 0, 5)!:        $\C{\# Mon : 1 Tue : 2 Wed : 3 Thu : 4 Fri : 5}$
1139        print( day.name, ":", day.value, end=" " )
1140for day in !islice(Week, 5, 7)!:        $\C{\# Sat : 6 Sun : 7}$
1141        print( day.name, ":", day.value, end=" " )
1142for day in !islice(Week,0, 7, 2)!:      $\C{\# Mon : 1 Wed : 3 Fri : 5 Sun : 7}\CRT$
1143        print( day.name, ":", day.value, end=" " )
1144\end{python}
1145Iterating that includes alias names only (strings) is done using attribute @__members__@.
1146\begin{python}
1147for day in WeekD.__members__:
1148        print( day, ":", end=" " )
1149Mon : Tue : Wed : Thu : Fri : Sat : Sun
1150\end{python}
1151
1152Enumeration subclassing is allowed only if the enumeration base-class does not define any members.
1153\begin{python}
1154class WeekE(OrderedEnum): !pass!;  # no members
1155class WeekDay(WeekE): Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5;
1156class WeekEnd(WeekE): Sat = 6; Sun = 7
1157\end{python}
1158Here, type @WeekE@ is an abstract type because dynamic typing never uses it.
1159\begin{cquote}
1160\setlength{\tabcolsep}{25pt}
1161\begin{tabular}{@{}ll@{}}
1162\begin{python}
1163print( type(WeekE) )
1164day : WeekE = WeekDay.Fri       # set type
1165print( type(day), day )
1166day = WeekEnd.Sat                           # set type
1167print( type(day), day )
1168\end{python}
1169&
1170\begin{python}
1171<$class$ 'enum.EnumType'>
1172
1173<enum 'WeekDay'> WeekDay.Fri
1174
1175<enum 'WeekEnd'> WeekEnd.Sat
1176\end{python}
1177\end{tabular}
1178\end{cquote}
1179
1180There are a number of supplied enumeration base-types: @IntEnum@, @StrEnum@, @IntFalg@, @Flag@, which restrict the values in an enum using multi-inheritance.
1181@IntEnum@ is a subclass of @int@ and @Enum@, allowing enumerator comparison to @int@ and other enumerators of this type (like C enumerators).
1182@StrEnum@ is the same as @IntEnum@ but a subclass of the string type \lstinline[language=python]{str}.
1183@IntFlag@, is a restricted subclass of @int@ where the enumerators can be combined using the bitwise operators (@&@, @|@, @^@, @~@) and the result is an @IntFlag@ member.
1184@Flag@ is the same as @IntFlag@ but cannot be combined with, nor compared against, any other @Flag@ enumeration, nor @int@.
1185Auto increment for @IntFlag@ and @Flag@ is by powers of 2.
1186Enumerators that are combinations of single-bit enumerators are aliases and, hence, invisible.
1187The following is an example for @Flag@.
1188\begin{python}
1189class WeekF(Flag): Mon = 1; Tue = 2; Wed = 4; Thu = !auto()!; Fri = 16; Sat = 32; Sun = 64; \
1190          Weekday = Mon | Tue | Wed | Thu | Fri; \
1191          Weekend = Sat | Sun
1192print( f"0x{repr(WeekF.Weekday.value)} 0x{repr(WeekF.Weekend.value)}" )
11930x31 0x96
1194\end{python}
1195It is possible to enumerate through a @Flag@ enumerator (no aliases):
1196\begin{python}
1197for day in WeekF:
1198        print( f"{day.name}: {day.value}", end=" ")
1199Mon: 1 Tue: 2 Wed: 4 Thu: 8 Fri: 16 Sat: 32 Sun: 64 
1200\end{python}
1201and a combined alias enumerator for @Flag@.
1202\begin{cquote}
1203\setlength{\tabcolsep}{15pt}
1204\begin{tabular}{@{}ll@{}}
1205\begin{python}
1206weekday = WeekF.Weekday
1207for day in weekday:
1208        print( f"{day.name}:"
1209                   f" {day.value}", end=" " )
1210Mon: 1 Tue: 2 Wed: 4 Thu: 8 Fri: 16 
1211\end{python}
1212&
1213\begin{python}
1214weekend = WeekF.Weekend
1215for day in weekend:
1216        print( f"{day.name}:"
1217                   f" {day.value}", end=" " )
1218Sat: 32 Sun: 64 
1219\end{python}
1220\end{tabular}
1221\end{cquote}
1222
1223
1224\section{OCaml}
1225
1226% https://ocaml.org/docs/basic-data-types#enumerated-data-types
1227% https://dev.realworldocaml.org/runtime-memory-layout.html
1228
1229Like Swift (\VRef{s:Swift}) and Haskell (\VRef{s:AlgebraicDataType}), OCaml @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration.
1230When @enum@ is an ADT, pattern matching is used to discriminate among the variant types.
1231\begin{cquote}
1232\setlength{\tabcolsep}{20pt}
1233\begin{tabular}{@{}l@{\hspace{35pt}}ll@{}}
1234\begin{ocaml}
1235type s = { i : int; j : int }
1236let sv : s = { i = 3; j = 5 }
1237@type@ adt =
1238        I of int |    $\C[1in]{// int}$
1239        F of float |  $\C{// float}$
1240        S of s        $\C{// struct}\CRT$
1241
1242
1243\end{ocaml}
1244&
1245\begin{ocaml}
1246let adtprt( adtv : adt ) =
1247        @match@ adtv with (* pattern matching *)
1248                I i -> printf "%d\n" i |
1249                F f -> printf "%g\n" f |
1250                S sv -> printf "%d %d\n" sv.i sv.j
1251let adtv : adt = I(3)       let _ = adtprt( adtv )
1252let adtv : adt = F(3.5)   let _ = adtprt( adtv )
1253let adtv : adt = S(sv)    let _ = adtprt( adtv )
1254\end{ocaml}
1255&
1256\begin{ocaml}
12573
12583.5
12593 5
1260
1261
1262
1263
1264
1265\end{ocaml}
1266\end{tabular}
1267\end{cquote}
1268% (Note, after an @adtv@'s type is know, the enumerator is inferred without qualification, \eg @I(3)@.)
1269
1270The type names are independent of the type value and mapped to an opaque, ascending, integral tag, starting from 0, supporting relational operators @<@, @<=@, @>@, and @>=@.
1271\begin{cquote}
1272\setlength{\tabcolsep}{10pt}
1273\begin{tabular}{@{}l@{\hspace{25pt}}ll@{}}
1274\begin{ocaml}
1275let silly( adtv : adt ) =
1276        if adtv <= F(3.5) then
1277                printf "<= F\n"
1278        else if adtv >= S(sv) then
1279                printf ">= S\n"
1280\end{ocaml}
1281&
1282\begin{ocaml}
1283let adtv : adt = I(3)       let _ = silly( adtv )
1284let adtv : adt = F(3.5)   let _ = silly( adtv )
1285let adtv : adt = S(sv)    let _ = silly( adtv )
1286
1287
1288\end{ocaml}
1289&
1290\begin{ocaml}
1291<= F
1292<= F
1293>= S
1294
1295
1296\end{ocaml}
1297\end{tabular}
1298\end{cquote}
1299In the example, type values must be specified (any appropriate values work) but ignored in the relational comparison of the type tag.
1300
1301An enumeration is created when \emph{all} the enumerators are unit-type, which is like a scoped, opaque enumeration, where only the type tag is used.
1302\begin{ocaml}
1303type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun
1304let day : week = Mon
1305\end{ocaml}
1306Since the type names are opaque, a type-tag value cannot be explicitly set nor can it have a type other than integral.
1307
1308As seen, a type tag can be used in the @if@ and \lstinline[language=ocaml]{match} statements, where \lstinline[language=ocaml]{match} must be exhaustive or have a default case.
1309
1310While OCaml enumerators have an ordering following the definition order, they are not enumerable.
1311To iterate over all enumerators, an OCaml type needs to derive from the @enumerate@ PPX (Pre-Preocessor eXtension), which appends a list of all enumerators to the program abstract syntax tree (AST).
1312However, as stated in the documentation, @enumerate@ PPX does not guarantee the order of the list.
1313PPX is beyond the scope of OCaml native language and it is a preprocessor directly modifying a parsed AST. In conclusion, there is no enumerating mechanism within the scope of OCaml language.
1314
1315New types can be formed as a composition of existing types.
1316\begin{ocaml}
1317type weekday = Mon | Tue | Wed | Thu | Fri
1318type weekend = Sat | Sun
1319type week = Weekday of weekday | Weekend of weekend
1320let day : week = Weekend Sun
1321\end{ocaml}
1322The type @week@ is the sum of @weekday@ and @weekend@, \ie @week@ has all the enumerators from the set @weekday@ and @weekend@.
1323The sum type construction resembles containment inheritance from non-functional programming discipline, with the sum type being a wrapper class that contains one of its parent types.
1324The wrapper is unwrapped with pattern matching.
1325\begin{cquote}
1326\begin{tabular}{@{}ll@{}}
1327\begin{ocaml}
1328type weekday = Mon | Tue | Wed | Thu | Fri
1329type weekend = Sat | Sun
1330type week = Weekday of weekday |
1331                                 Weekend of weekend
1332let wd : weekday = Mon
1333let _ = match wd with
1334        Mon -> printf "Mon " | _ -> ()
1335let we : weekend = Sun
1336let _ = match we with
1337        Sun -> printf "Sun " | _ -> ()
1338let day : week = Weekend Sun
1339let _ = match day with
1340        Weekend Sun -> printf "Sun\n" | _ -> ()
1341
1342\end{ocaml}
1343&
1344\begin{cfa}
1345enum() weekday { Mon, Tue, Wed, Thu, Fri };
1346enum() weekend { Sat, Sun };
1347enum() week { inline weekday, inline weekend };
1348int main() {
1349        weekday wd = Mon;
1350
1351        printf( "%s ", label( wd ) );
1352        weekend we = Sun;
1353
1354        printf( "%s ", label( we ) );
1355        week day = Sun;
1356
1357        printf( "%s\n", label( day ) );
1358}
1359\end{cfa}
1360\\
1361\begin{cfa}
1362Mon Sun Sun
1363\end{cfa}
1364\end{tabular}
1365\end{cquote}
1366
1367%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1368
1369\begin{comment}
1370Date: Wed, 13 Mar 2024 10:52:34 -0400
1371Subject: Re: OCaml
1372To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>
1373From: Gregor Richards <gregor.richards@uwaterloo.ca>
1374
1375On 3/12/24 18:34, Peter A. Buhr wrote:
1376> Gregor, attached is a section Jiada wrote on OCaml (1-page).
1377> Does it reflect our discussion about functional languages and enumerations?
1378
1379Yeah, I think so. The most important part, i.e., that once they're
1380parameterized they're not really enumerations at all, is covered clearly
1381enough.
1382
1383A couple quibbles:
1384
1385<<a list of untyped tags>>
1386
1387This is true, but leaking implementation details. These are nullary datatype
1388constructors. Indeed, you later talk about "tagged variants", which are really
1389just parameterized variants, using the term "tag" differently, confusing the
1390term "tag" further.
1391
1392<<Because week is a summation of values Mon to Sun, it is a sum type in
1393turns of the functional-programming paradigm>>
1394
1395It is a *union* of values and is a *union* type.
1396
1397With valediction,
1398  - Gregor Richards
1399
1400
1401Date: Thu, 14 Mar 2024 21:45:52 -0400
1402Subject: Re: OCaml "enums" do come with ordering
1403To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>
1404From: Gregor Richards <gregor.richards@uwaterloo.ca>
1405
1406On 3/14/24 21:30, Peter A. Buhr wrote:
1407> I've marked 3 places with your name to shows places with enum ordering.
1408>
1409> open Printf
1410> type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun
1411> let day : week = Mon
1412> let take_class( d : week ) =
1413>       if d <= Fri then                                (* Gregor *)
1414>               printf "week\n"
1415>       else if d >= Sat then                   (* Gregor *)
1416>               printf "weekend\n";
1417>       match d with
1418>               Mon | Wed -> printf "CS442\n" |
1419>               Tue | Thu -> printf "CS343\n" |
1420>               Fri -> printf "Tutorial\n" |
1421>               _ -> printf "Take a break\n"
1422>
1423> let _ = take_class( Mon ); take_class( Sat );
1424>
1425> type colour = Red | Green of string | Blue of int * float
1426> let c = Red
1427> let _ = match c with Red -> printf "Red, "
1428> let c = Green( "abc" )
1429> let _ = match c with Green g -> printf "%s, " g
1430> let c = Blue( 1, 1.5 )
1431> let _ = match c with Blue( i, f ) -> printf "%d %g\n" i f
1432>
1433> let check_colour(c: colour): string =
1434>       if c < Green( "xyz" ) then              (* Gregor *)
1435>               printf "green\n";
1436>       match c with
1437>               Red -> "Red" |
1438>               Green g -> g |
1439>               Blue(i, f) -> string_of_int i ^ string_of_float f
1440> let _ = check_colour( Red ); check_colour( Green( "xyz" ) );
1441>
1442> type stringList = Empty | Pair of string * stringList
1443> let rec len_of_string_list(l: stringList): int =
1444>       match l with
1445>               Empty -> 0 |
1446>               Pair(_ , r) -> 1 + len_of_string_list r
1447>
1448> let _ = for i = 1 to 10 do
1449>       printf "%d, " i
1450> done
1451>
1452> (* Local Variables: *)
1453> (* tab-width: 4 *)
1454> (* compile-command: "ocaml test.ml" *)
1455> (* End: *)
1456
1457My functional-language familiarity is far more with Haskell than OCaml.  I
1458mostly view OCaml through a lens of "it's Haskell but with cheating".  Haskell
1459"enums" (ADTs) aren't ordered unless you specifically and manually put them in
1460the Ord typeclass by defining the comparators.  Apparently, OCaml has some
1461other rule, which I would guess is something like "sort by tag then by order of
1462parameter". Having a default behavior for comparators is *bizarre*; my guess
1463would be that it gained this behavior in its flirtation with object
1464orientation, but that's just a guess (and irrelevant).
1465
1466This gives a total order, but not enumerability (which would still be
1467effectively impossible or even meaningless since enums are just a special case
1468of ADTs).
1469
1470With valediction,
1471  - Gregor Richards
1472
1473Date: Wed, 20 Mar 2024 18:16:44 -0400
1474Subject: Re:
1475To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>
1476From: Gregor Richards <gregor.richards@uwaterloo.ca>
1477
1478
1479On 3/20/24 17:26, Peter A. Buhr wrote:
1480> Gregor, everyone at this end would like a definition of "enumerability". Can
1481> you formulate one?
1482
1483According to the OED (emphasis added to the meaning I'm after):
1484
1485enumerate (verb, transitive). To count, ascertain the number of; **more
1486usually, to mention (a number of things or persons) separately, as if for the
1487purpose of counting**; to specify as in a list or catalogue.
1488
1489With C enums, if you know the lowest and highest value, you can simply loop
1490over them in a for loop (this is, of course, why so many enums come with an
1491ENUM_WHATEVER_LAST value). But, I would be hesitant to use the word "loop" to
1492describe enumerability, since in functional languages, you would recurse for
1493such a purpose.
1494
1495In Haskell, in order to do something with every member of an "enumeration", you
1496would have to explicitly list them all. The type system will help a bit since
1497it knows if you haven't listed them all, but you would have to statically have
1498every element in the enumeration.  If somebody added new elements to the
1499enumeration later, your code to enumerate over them would no longer work
1500correctly, because you can't simply say "for each member of this enumeration do
1501X". In Haskell that's because there aren't actually enumerations; what they use
1502as enumerations are a degenerate form of algebraic datatypes, and ADTs are
1503certainly not enumerable. In OCaml, you've demonstrated that they impose
1504comparability, but I would still assume that you can't make a loop over every
1505member of an enumeration. (But, who knows!)
1506
1507Since that's literally what "enumerate" means, it seems like a rather important
1508property for enumerations to have ;)
1509
1510With valediction,
1511  - Gregor Richards
1512
1513
1514From: Andrew James Beach <ajbeach@uwaterloo.ca>
1515To: Gregor Richards <gregor.richards@uwaterloo.ca>, Peter Buhr <pabuhr@uwaterloo.ca>
1516CC: Michael Leslie Brooks <mlbrooks@uwaterloo.ca>, Fangren Yu <f37yu@uwaterloo.ca>,
1517        Jiada Liang <j82liang@uwaterloo.ca>
1518Subject: Re: Re:
1519Date: Thu, 21 Mar 2024 14:26:36 +0000
1520
1521Does this mean that not all enum declarations in C create enumerations? If you
1522declare an enumeration like:
1523
1524enum Example {
1525        Label,
1526        Name = 10,
1527        Tag = 3,
1528};
1529
1530I don't think there is any way to enumerate (iterate, loop, recurse) over these
1531values without listing all of them.
1532
1533
1534Date: Thu, 21 Mar 2024 10:31:49 -0400
1535Subject: Re:
1536To: Andrew James Beach <ajbeach@uwaterloo.ca>, Peter Buhr <pabuhr@uwaterloo.ca>
1537CC: Michael Leslie Brooks <mlbrooks@uwaterloo.ca>, Fangren Yu <f37yu@uwaterloo.ca>,
1538    Jiada Liang <j82liang@uwaterloo.ca>
1539From: Gregor Richards <gregor.richards@uwaterloo.ca>
1540
1541I consider this conclusion reasonable. C enums can be nothing more than const
1542ints, and if used in that way, I personally wouldn't consider them as
1543enumerations in any meaningful sense, particularly since the type checker
1544essentially does nothing for you there. Then they're a way of writing consts
1545repeatedly with some textual indicator that these definitions are related; more
1546namespace, less enum.
1547
1548When somebody writes bitfield members as an enum, is that *really* an
1549enumeration, or just a use of the syntax for enums to keep related definitions
1550together?
1551
1552With valediction,
1553  - Gregor Richards
1554
1555
1556Date: Tue, 16 Apr 2024 11:04:51 -0400
1557Subject: Re: C unnamed enumeration
1558To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>
1559CC: <ajbeach@uwaterloo.ca>, <j82liang@uwaterloo.ca>, <mlbrooks@uwaterloo.ca>,
1560        <f37yu@uwaterloo.ca>
1561From: Gregor Richards <gregor.richards@uwaterloo.ca>
1562
1563On 4/16/24 09:55, Peter A. Buhr wrote:
1564> So what is a variant? Is it a set of tag names, which might be a union or is it
1565> a union, which might have tag names?
1566
1567Your tagless variant bears no resemblance to variants in any functional
1568programming language. A variant is a tag AND a union. You might not need to put
1569anything in the union, in which case it's a pointless union, but the named tag
1570is absolutely mandatory. That's the thing that varies.
1571
1572I was unaware of std::variant. As far as functional languages are concerned,
1573std::variant IS NOT A VARIANT. Perhaps it would be best to use the term ADT for
1574the functional language concept, because that term has no other meanings.
1575
1576An ADT cannot not have a named tag. That's meaningless. The tag is the data
1577constructor, which is the thing you actually define when you define an ADT. It
1578is strictly the union that's optional.
1579
1580With valediction,
1581  - Gregor Richards
1582\end{comment}
1583
1584
1585\section{Comparison}
1586
1587\VRef[Table]{t:FeatureLanguageComparison} shows a comparison of enumeration features and programming languages with the explaination of categories below.
1588The features are high-level and may not capture nuances within a particular language.
1589
1590\begin{table}
1591\caption{Enumeration Feature / Language Comparison}
1592\label{t:FeatureLanguageComparison}
1593\small
1594\setlength{\tabcolsep}{3pt}
1595\newcommand{\CM}{\checkmark}
1596\begin{tabular}{r|c|c|c|c|c|c|c|c|c|c|c|c|c}
1597                                &Pascal & Ada                   &\Csharp   & OCaml  & Java      &Golang   & Rust                & Swift                 & Python& C             & \CC   & \CFA  \\
1598\hline
1599enum                    &Dialect& \CM                   & \CM      & ADT    & \CM   & @const@ &ADT/\CM      &ADT/\CM            & \CM   &\CM    &\CM   &\CM\\
1600\hline
1601\hline
1602opaque                  & \CM    &                              &                  & \CM    & \CM   &             & \CM         & \CM                   &               &               &               & \CM   \\
1603\hline
1604typed                   & Int    & Int                  & Int     & H     & U     & H       & U/H         & U/H           & H       & Int       & Int   & U     \\
1605\hline
1606safety          & \CM   & \CM                   &          & \CM        & \CM   &                 & \CM                 & \CM                   &               &               & \CM   & \CM   \\
1607\hline
1608posn ordered    & Implied & Implied     &          & \CM    &       &             &                         &                   &       &           &       & \CM       \\
1609\hline
1610unique values   & \CM   & \CM           &           &\CM        &       &      &                            & \CM               &       &           &       &     \\
1611\hline
1612auto-init               & \CM   & all or none   & \CM      & N/A &       & \CM     & \CM            & \CM               & \CM   & \CM   & \CM   & \CM   \\
1613\hline
1614(Un)Scoped              & U     & U                     & S        & S      & S         & U       & S               & S                         & S     & U             & U/S   & U/S   \\
1615\hline
1616overload                &               & \CM                   &              &            &      &              &                 &                       &      &            &       & \CM   \\
1617\hline
1618loop                    & \CM   & \CM                   &                  &            &               &                 &                         &                   & \CM   &               &               & \CM   \\
1619\hline
1620arr. dim.               & \CM   & \CM           &                  &              &                 &           &                 &                         &            &      &               & \CM \\
1621\hline
1622subset                  & \CM   & \CM                   &         &      &              &                 &                         &                   &               &               &               & \CM   \\
1623\hline
1624superset                &               &                               &                 &                 &           &                 &                         &               &           &               &               & \CM   \\
1625\end{tabular}
1626\end{table}
1627
1628\begin{enumerate}
1629\item opaque: an enumerator cannot be used as its underlying representation or implemented in terms of an ADT.
1630\item typed: H $\Rightarrow$ heterogeneous, \ie enumerator values may be different types. \\
1631U $\Rightarrow$ homogenous, \ie enumerator values have the same type.
1632\item safety: An enumeration variable can only hold a value from its defined enumerators.
1633\item posn ordered: enumerators have defined ordering based on enumerator declaration order.
1634Position ordered is implied if the enumerator values must be strictly increasingly.
1635\item unique value: enumerators must have a unique value.
1636\item auto-init: Values are auto-initializable by language specification. \\
1637It is not appliable to OCaml because OCaml enumeration has unit type.
1638\item (Un)Scoped: U $\Rightarrow$ enumerators are projected into the containing scope.
1639S $\Rightarrow$ enumerators are contained in the enumeration scope and require qualification.
1640\item overload: An enumerator label can be used without type qualification in a context where multiple enumerations have defined the label.
1641\item loop: Enumerate without the need to convert an enumeration to another data structure.
1642\item arr. dim: An enumeration can be used directly as an array dimension, and enumerators can be mapped to an array element (not a conversion to integer type).
1643\item subset: Name a subset of enumerators as a new type.
1644\item superset: Create a new enumeration that contains all enumerators from pre-defined enumerations.
1645\end{enumerate}
Note: See TracBrowser for help on using the repository browser.