source: doc/theses/jiada_liang_MMath/relatedwork.tex @ c329bca

Last change on this file since c329bca was 0bda8d7, checked in by JiadaL <j82liang@…>, 5 weeks ago

Small updates

  • Property mode set to 100644
File size: 62.4 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@,
499a static member of abstract Enum type that return a reference to an array of all enumeration constants.
500Internally, an Enum type has a static member called @fieldInfoHash@ -- a @Hashtable@ that stores information about enumerators.
501The field is populated on-demand: it only contains information if a @reflection@ like @GetValues@ is called.
502As an optimization, this information is cached, so the cost of reflection is paid once throughout the lifetime of a program.
503@GetValues@ then converts a @Hashtable@ to an @Array@, which supports enumerating.
504\begin{csharp}
505foreach ( Week d in @Enum.GetValues@( typeof(Week) ) ) {
506        Console.WriteLine( d + " " + (int)d + " " ); // label, position
507}
508Mon 0, Tue 1, Wed 2, Thu 10, Fri 11, Sat 12, Sun 13,
509\end{csharp}
510Hence, 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.
511
512An enumeration type cannot declare an array dimension but an enumerator can be used as a subscript.
513There is no mechanism to subset or inherit from an enumeration.
514
515The @Flags@ attribute creates a bit-flags enumeration, making bitwise operators @&@, @|@, @~@ (complement), @^@ (xor) sensible.
516\begin{csharp}
517@[Flags]@ public enum Week {
518        None = 0x0, Mon = 0x1, Tue = 0x2, Wed = 0x4,
519        Thu = 0x8, Fri = 0x10, Sat = 0x20, Sun = 0x40,
520        Weekdays = @Mon | Tue | Wed | Thu | Fri@ $\C{// Weekdays == 0x1f}$
521        Weekend = @Sat | Sun@,                  $\C{// Weekend == 0x60}$
522}
523Week meetings = @Week.Mon | Week.Wed@; $\C{// 0x5}$
524\end{csharp}
525
526
527\section{Go}
528\label{s:Go}
529
530Go has @const@ aliasing declarations, similar to \CC \see{\VRef{s:C++RelatedWork}}, for basic types with type inferencing and static initialization (constant expression).
531The 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.
532For example:
533\begin{Go}
534const R @int@ = 0;  const G @uint@ = 1;  const B = 2; $\C{// explicit typing and type inferencing}$
535const Fred = "Fred";  const Mary = "Mary";  const Jane = "Jane";
536const S = 0;  const T = 0;
537const USA = "USA";  const U = "USA";
538const V = 3.1;  const W = 3.1;
539\end{Go}
540These declarations defined immutable and unscoped variables, and Go has no naming overloading. If no type declaration is provided, Go infers
541type from the initializer expression.
542
543% Go provides an enumeration-like feature to group together @const@ declaration into a block and introduces a form of auto-initialization.
544These named constants can be grouped together in one @const@ declaration block to introduce a form of auto-initialization.
545\begin{Go}
546const ( R = 0; G; B )                                   $\C{// implicit initialization: 0 0 0}$
547const ( Fred = "Fred"; Mary = "Mary"; Jane = "Jane" ) $\C{// explicit initialization: Fred Mary Jane}$
548const ( S = 0; T; USA = "USA"; U; V = 3.1; W ) $\C{// implicit/explicit: 0 0 USA USA 3.1 3.1}$
549\end{Go}
550The first identifier \emph{must} be explicitly initialized;
551subsequent identifiers can be implicitly or explicitly initialized.
552Implicit initialization always uses the \emph{previous} (predecessor) constant expression initializer.
553A constant block can still use explicit declarations, and the following constants inherit that type.
554\begin{Go}
555type BigInt int64
556const ( R @BigInt@ = 0; G; B )
557const ( Fred @string@ = "Fred"; Mary = "Mary"; Jane = "Jane" )
558const ( S @int@ = 0; T; USA @string@ = "USA"; U; V @float32@ = 3.1; W )
559\end{Go}
560Typing the first constant and implicit initializing is still not an enumeration because there is no unique type for the constant block;
561Nothing stops other constant blocks from being of the same type.
562
563Each @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.
564% Each @const@ declaration is often paired with a const expression \lstinline[language=Go]{iota} to re-define its implicit initialization.
565% \lstinline[language=Go]{iota} represents a sequence of natural numbers starting from zero.
566% Using \lstinline[language=Go]{iota} outside of a @const@ block always sets the identifier to zero.
567% \begin{Go}
568% const R = iota;                                                       $\C{// 0}$
569% \end{Go}
570% 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.
571% Inside a @const@ block, if a constant has \lstinline[language=Go]{iota} initializer, its successor will also use \lstinline[language=Go]{iota} initializer.
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% \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.
574\begin{Go}
575const ( R = @iota@; G; B )                                      $\C{// implicit: 0 1 2}$
576const ( C = @iota + B + 1@; G; Y )                      $\C{// implicit: 3 4 5}$
577\end{Go}
578which are equivalent to:
579\begin{Go}
580const ( R = @iota@; G = @iota@; B = @iota@ ) $\C{// implicit: 0 1 2}$
581const ( C = @iota + B + 1@; G = @iota + B + 1@; Y = @iota + B + 1@ ) $\C{// implicit: 3 4 5}$
582\end{Go}
583An underscore \lstinline[language=golang]{const} identifier advances \lstinline[language=Go]{iota}.
584\begin{Go}
585const ( O1 = iota + 1; @_@; O3; @_@; O5 )       $\C{// 1, 3, 5}$
586\end{Go}
587Auto-initialization reverts from \lstinline[language=Go]{iota} to the previous value after an explicit initialization, but auto-incrementing of \lstinline[language=Go]{iota} continues.
588\begin{Go}
589const ( Mon = iota; Tue; Wed;                           $\C{// 0, 1, 2}$
590                 @Thu = 10@; Fri; Sat; @Sun = iota@ ) $\C{// 10, 10, 10, {\color{red}6}}$
591\end{Go}
592Auto-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}.
593\begin{Go}
594const ( V1 = iota; V2; @V3 = 7;@ V4 = @iota@ + 1; V5 ) // 0 1 7 4 5
595const ( Mon = iota; Tue; Wed; // 0, 1, 2
596                @Thu = 10;@ Fri = @iota@ - Wed + Thu - 1; Sat; Sun ) // 10, 11, 12, 13
597\end{Go}
598Here, @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}.
599Note, because \lstinline[language=Go]{iota} is incremented for an explicitly initialized identifier or @_@,
600at @Fri@ \lstinline[language=Go]{iota} is 4 requiring the minus one to compute the value for @Fri@.
601
602Basic switch and looping are possible.
603\begin{cquote}
604\setlength{\tabcolsep}{20pt}
605\begin{tabular}{@{}ll@{}}
606\begin{Go}
607day := Mon;     // := $\(\Rightarrow\)$ type inferencing
608switch @day@ {
609  case Mon, Tue, Wed, Thu, Fri:
610        fmt.Println( "weekday" );
611  case Sat, Sun:
612        fmt.Println( "weekend" );
613}
614\end{Go}
615&
616\begin{Go}
617
618for i := @Mon@; i <= @Sun@; i += 1 {
619        fmt.Println( i )
620}
621
622
623
624\end{Go}
625\end{tabular}
626\end{cquote}
627However, the loop in this example prints the values from 0 to 13 because there is no actual enumeration.
628
629A constant variable can be used as an array dimension or a subscript.
630\begin{Go}
631var ar[@Sun@] int
632ar[@Mon@] = 3
633\end{Go}
634
635
636\section{Java}
637
638Java provides an enumeration using a specialized class.
639A basic Java enumeration is an opaque enumeration, where the enumerators are constants.
640\begin{Java}
641enum Week { Mon, Tue, Wed, Thu, Fri, Sat, Sun; }
642Week day = Week.Sat;
643\end{Java}
644The enumerator's members are scoped, requiring qualification.
645The value of an enumeration instance is restricted to its enumerators.
646
647The position (ordinal) and label (name) are accessible but there is no value property.
648\begin{Java}
649System.out.println( day.!ordinal()! + " " + !day! + " " + day.!name()! );
6505 Sat Sat
651\end{Java}
652Since @day@ has no value, it prints its label (name).
653The member @valueOf@ is the inverse of @name@ converting a string to an enumerator.
654\begin{Java}
655day = Week.valueOf( "Wed" );
656\end{Java}
657Extra members can be added to provide specialized operations.
658\begin{Java}
659public boolean isWeekday() { return !ordinal()! <= Fri.ordinal(); }
660public boolean isWeekend() { return Sat.ordinal() <= !ordinal()!; }
661\end{Java}
662Notice the unqualified calls to @ordinal@ in the members implying a \lstinline[language=Java]{this} to some implicit implementation variable, likely an @int@.
663
664Enumerator values require an enumeration type (any Java type may be used) and implementation member.
665\begin{Java}
666enum Week {
667        Mon!(1)!, Tue!(2)!, Wed!(3)!, Thu!(4)!, Fri!(5)!, Sat!(6)!, Sun!(7)!; // must appear first
668        private !long! day;                                     $\C{// enumeration type and implementation member}$
669        private Week( !long! d ) { day = d; } $\C{// enumerator initialization}$
670};
671Week day = Week.Sat;
672\end{Java}
673The position, value, and label are accessible.
674\begin{Java}
675System.out.println( !day.ordinal()! + " " + !day.day! + " " + !day.name()! );
6765 6 Sat
677\end{Java}
678If 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@.
679The implementation constructor must be private since it is only used internally to initialize the enumerators.
680Initialization occurs at the enumeration-type declaration.
681
682Enumerations can be used in the @if@ and @switch@ statements but only for equality tests.
683\begin{cquote}
684\setlength{\tabcolsep}{15pt}
685\begin{tabular}{@{}ll@{}}
686\begin{Java}
687if ( !day! == Week.Fri )
688        System.out.println( "Fri" );
689
690
691
692
693\end{Java}
694&
695\begin{Java}
696switch ( !day! ) {
697  case Mon: case Tue: case Wed: case Thu: case Fri:
698        System.out.println( "weekday" );  break;
699  case Sat: case Sun:
700        System.out.println( "weekend" );  break;
701}
702\end{Java}
703\end{tabular}
704\end{cquote}
705Notice enumerators in the @switch@ statement do not require qualification.
706
707There 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}.
708Like \Csharp, enumerating is supplied indirectly through another enumerable type, not via the enumeration.
709Specifically, Java supplies a static method @values@, which returns an array of enumerator values.
710Unfortunately, @values@ is an expensive @O(n)@ operation, which is recreated each time it is called.
711\begin{Java}
712for ( Week d : Week.values() ) {
713        System.out.print( d.ordinal() + d.day + " " +  d.name() + ",  " );
714}
7150 1 Mon,  1 2 Tue,  2 3 Wed,  3 4 Thu,  4 5 Fri,  5 6 Sat,  6 7 Sun, 
716\end{Java}
717
718% 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.
719% There is also a specialized version of @HashMap@ with enumerator keys, which has performance benefits.
720Java 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.
721@EnumSet@ is enumerable because it extends @AbstractSet@ interfaces and thus supports direct enumerating via @forEach@.
722It also has subset operation @range@ and it is possible to add to and remove from members of the set.
723@EnumSet@ supports more enumeration features, but it is not an enumeration type; it is a set of enumerators from a pre-defined enum.
724
725An enumeration type cannot declare an array dimension nor can an enumerator be used as a subscript.
726Enumeration inheritence is disallowed because an enumeration is \lstinline[language=Java]{final}.
727
728
729\section{Rust}
730
731% https://doc.rust-lang.org/reference/items/enumerations.html
732
733Rust @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration.
734When @enum@ is an ADT, pattern matching is used to discriminate among the variant types.
735\begin{cquote}
736\begin{tabular}{@{}l@{\hspace{30pt}}ll@{}}
737\begin{rust}
738struct S {
739        i : isize,  j : isize
740}
741let mut s = S{ i : 3, j : 4 };
742enum @ADT@ {
743        I( isize ), $\C[1in]{// int}$
744        F( f64 ),   $\C{// float}$
745        S( S ),     $\C{// struct}\CRT$
746}
747\end{rust}
748&
749\begin{rust}
750let mut adt : ADT;
751adt = ADT::I(3);  println!( "{:?}", adt );
752adt = ADT::F(3.5);  println!( "{:?}", adt );
753adt = ADT::S(s);  println!( "{:?}", adt );
754@match@ adt {
755        ADT::I( i ) $=>$ println!( "{:}", i ),
756        ADT::F( f ) $=>$ println!( "{:}", f ),
757        ADT::S( s ) $=>$ println!( "{:} {:}", s.i, s.j ),
758}
759\end{rust}
760&
761\begin{rust}
762I(3)
763F(3.5)
764S(S { i: 3, j: 4 })
7653 4
766
767
768
769
770
771\end{rust}
772\end{tabular}
773\end{cquote}
774Even when the variant types are the unit type, the ADT is still not an enumeration because there is no enumerating \see{\VRef{s:AlgebraicDataType}}.
775\begin{rust}
776enum Week { Mon, Tues, Wed, Thu, Fri, Sat, Sun@,@ } // terminating comma
777let mut week : Week = Week::Mon;
778match week {
779        Week::Mon $=>$ println!( "Mon" ),
780        ...
781        Week::Sun $=>$ println!( "Sun" ),
782}
783\end{rust}
784
785However, Rust allows direct setting of the ADT constructor, which means it is actually a tag.
786\begin{cquote}
787\setlength{\tabcolsep}{15pt}
788\begin{tabular}{@{}ll@{}}
789\begin{rust}
790enum Week {
791        Mon, Tues, Wed, // start 0
792        Thu @= 10@, Fri,
793        Sat, Sun,
794}
795
796\end{rust}
797&
798\begin{rust}
799#[repr(u8)]
800enum ADT {
801        I(isize) @= 5@,
802        F(f64) @= 10@,
803        S(S) @= 0@,
804}
805\end{rust}
806\end{tabular}
807\end{cquote}
808Through 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}.
809When tags represent non-unit types, Rust largely precludes accessing the tag because the semantics become meaningless.
810Hence, the two mechanisms are largely disjoint, and only the enumeration component is discussed.
811
812In detail, the @enum@ type has an implicit integer tag (discriminant) with a unique value for each variant type.
813Direct initialization is achieved by a compile-time expression that generates a constant value.
814Indirect initialization (without initialization, @Fri@/@Sun@) is auto-initialized: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@.
815There is an explicit cast from the tag to integer.
816\begin{rust}
817let mut mon : isize = Week::Mon as isize;
818\end{rust}
819An enumeration can be used in the @if@ and \lstinline[language=rust]{match} (@switch@) statements.
820\begin{cquote}
821\setlength{\tabcolsep}{8pt}
822\begin{tabular}{@{}ll@{}}
823\begin{c++}
824if @week as isize@ == Week::Mon as isize {
825        println!( "{:?}", week );
826}
827
828
829\end{c++}
830&
831\begin{c++}
832match @week@ {
833        Week::Mon | Week:: Tue | Week::Wed | Week::Thu
834                | Week::Fri => println!( "weekday" ),
835        Week::Sat | Week:: Sun $=>$ println!( "weekend" ),
836}
837\end{c++}
838\end{tabular}
839\end{cquote}
840% However, there is no mechanism to iterate through an enumeration without casting to integral and positions versus values is not handled.
841Like C/\CC, there is no mechanism to iterate through an enumeration.
842It can only be approximated by a loop over a range of enumerators and only works if the enumerator values are a sequence of natural numbers.
843\begin{c++}
844for d in Week::Mon as isize ..= Week::Sun as isize {
845        print!( "{:?} ", d );
846}
8470 1 2 @3 4 5 6 7 8 9@ 10 11 12 13
848\end{c++}
849% An enumeration type cannot declare an array dimension nor as a subscript.
850There is no direct way to harmonize an enumeration and another data structure.
851For example, there is no mapping from an enumerated type to an array type.
852In terms of extensibility, there is no mechanism to subset or inherit from an enumeration.
853
854
855\section{Swift}
856\label{s:Swift}
857% https://www.programiz.com/swift/online-compiler
858Despite being named as enumeration, a Swift @enum@ is in fact a ADT: cases (enumerators) of an @enum@ can have heterogeneous types and be recursive.
859% Like Rust, Swift @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration.
860When @enum@ is an ADT, pattern matching is used to discriminate among the variant types.
861\begin{cquote}
862\setlength{\tabcolsep}{20pt}
863\begin{tabular}{@{}l@{\hspace{55pt}}ll@{}}
864\begin{swift}
865struct S {
866        var i : Int,  j : Int
867}
868var s = S( i : 3, j : 5 )
869@enum@ ADT {
870        case I(Int)   $\C[1.125in]{// int}$
871        case F(Float) $\C{// float}$
872        case S(S)     $\C{// struct}\CRT$
873}
874\end{swift}
875&
876\begin{swift}
877var adt : ADT
878adt = .I( 3 );  print( adt )
879adt = .F( 3.5 );  print( adt )
880adt = .S( s );  print( adt )
881@switch@ adt {  // pattern matching
882        case .I(let i):  print( i )
883        case .F(let f):  print( f )
884        case .S(let s):  print( s.i, s.j )
885}
886\end{swift}
887&
888\begin{swift}
889I(3)
890F(3.5)
891S(S(i: 3, j: 5))
8923 5
893
894
895
896
897
898\end{swift}
899\end{tabular}
900\end{cquote}
901Note, after an @adt@'s type is known, the enumerator is inferred without qualification, \eg @.I(3)@.
902% Normally an enumeration case needs a type qualification.
903%However, when pattern matching @adt@ of type @ADT@, the @case@ context provides the type @ADT@ so no explicit type qualification is required.
904
905% An enumeration is created when \emph{all} the enumerators are unit-type, which is like a scoped, opaque enumeration.
906Without type declaration for enumeration cases, the enumerators have unit-type, which is like a scoped, opaque enumeration.
907\begin{swift}
908enum Week { case Mon, Tue, Wed, Thu, Fri, Sat, Sun }; // unit-type
909var week : Week = @Week.Mon@;
910\end{swift}
911% As well, it is possible to type \emph{all} the enumerators with a common type, and set different values for each enumerator;
912% for integral types, there is auto-incrementing.
913As well, it is possible to type associated values of enumeration cases with a common type.
914When enumeration cases are typed with a common integral type, Swift auto-initializes enumeration cases following the same initialization scheme as C language.
915If an enumeration is typed with @string@, its cases are auto-initialized to case names (labels).
916\begin{cquote}
917\setlength{\tabcolsep}{15pt}
918\begin{tabular}{@{}lll@{}}
919\begin{swift}
920enum WeekInt: @Int@ {
921        case Mon, Tue, Wed, Thu = 10, Fri,
922                        Sat = 4, Sun // auto-incrementing
923};
924\end{swift}
925&
926\begin{swift}
927enum WeekStr: @String@ {
928        case Mon = "MON", Tue, Wed, Thu, Fri,
929                        Sat = "SAT", Sun
930};
931\end{swift}
932\end{tabular}
933\end{cquote}
934An enumeration only supports equality comparison between enumerator values, unless it inherits from @Comparable@, adding relational operators @<@, @<=@, @>@, and @>=@.
935
936An enumeration can have methods.
937\begin{swift}
938enum Week: @Comparable@ {
939        case Mon, Tue, Wed, Thu, Fri, Sat, Sun // unit-type
940        func @isWeekday() -> Bool@ { return self <= .Fri }  // methods
941        func @isWeekend() -> Bool@ { return .Sat <= self }
942};
943\end{swift}
944An enumeration can be used in the @if@ and @switch@ statements, where @switch@ must be exhaustive or have a @default@.
945\begin{cquote}
946\setlength{\tabcolsep}{15pt}
947\begin{tabular}{@{}ll@{}}
948\begin{swift}
949if @week <= .Fri@ {
950        print( "weekday" );
951}
952
953
954\end{swift}
955&
956\begin{swift}
957switch @week@ {
958        case .Mon: print( "Mon" )
959        ...
960        case .Sun: print( "Sun" )
961}
962\end{swift}
963\end{tabular}
964\end{cquote}
965Enumerating 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.
966Like \CFA, Swift's default enumerator output is the case name (label). An enumerator of a typed enumeration has an attribute
967@rawValue@ that return its case value.
968\begin{swift}
969enum Week: Comparable, @CaseIterable@ {
970        case Mon, Tue, Wed, Thu, Fri, Sat, Sun // unit-type
971};
972for day in Week@.allCases@ {
973        print( day, terminator:" " ) 
974}
975Mon Tue Wed Thu Fri Sat Sun
976\end{swift}
977
978
979\begin{cquote}
980\setlength{\tabcolsep}{15pt}
981\begin{tabular}{@{}lll@{}}
982\begin{swift}
983enum WeekInt: @Int@, CaseIterable {
984        case Mon, Tue, Wed, Thu = 10, Fri,
985                        Sat = 4, Sun // auto-incrementing
986};
987for day in WeekInt.allCases {
988        print( day@.rawValue@, terminator:" " ) 
989}
9900 1 2 10 11 4 5 
991\end{swift}
992&
993\begin{swift}
994enum WeekStr: @String@, CaseIterable {
995        case Mon = "MON", Tue, Wed, Thu, Fri,
996                        Sat = "SAT", Sun
997};
998for day in WeekStr.allCases {
999        print( day@.rawValue@, terminator:" " ) 
1000}
1001MON Tue Wed Thu Fri SAT Sun
1002\end{swift}
1003\end{tabular}
1004\end{cquote}
1005
1006There is a safe bidirectional conversion from typed enumerator to @rawValue@ and vice versa.
1007\begin{swift}
1008if let opt = WeekInt( rawValue: 0 ) {  // test optional return value
1009        print( opt.rawValue, opt )  // 0 Mon
1010} else {
1011        print( "invalid weekday lookup" )
1012}
1013\end{swift}
1014% Conversion from @rawValue@ to enumerator may fail (bad lookup), so the result is an optional value.
1015In the previous example, the initialization of @opt@ fails if there is no enumeration value equal to 0, resulting in a @nil@ value.
1016Initialization from a raw value is considered an expensive operation because it requires a value lookup.
1017
1018
1019\section{Python 3.13}
1020% https://docs.python.org/3/howto/enum.html
1021
1022Python is a dynamically-typed reflexive programming language with multiple incompatible versions.
1023The generality of the language makes it possible to extend existing or build new language features.
1024As 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.
1025Therefore, the following discussion is (mostly) restricted to the core enumeration features in Python 3.13.
1026
1027A Python enumeration is not a basic type;
1028it is a @class@ inheriting from the @Enum@ class.
1029The @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.
1030Hence, an enumeration instance is a fixed type (enumeration pair), and its value is the type of one of the enumerator pairs.
1031
1032The enumerator value fields must be explicitly initialized and be \emph{unique}.
1033\begin{python}
1034class Week(!Enum!): Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7
1035\end{python}
1036and/or explicitly auto-initialized with @auto@ method, \eg:
1037\begin{python}
1038class Week(Enum): Mon = 1; Tue = 2; Wed = 3; Thu = 10; Fri = !auto()!; Sat = 4; Sun = !auto()!
1039Mon : 1 Tue : 2 Wed : 3 Thu : 10 Fri : !11! Sat : 4 Sun : !12!
1040\end{python}
1041@auto@ is controlled by member @_generate_next_value_()@, which by default returns one plus the highest value among enumerators, and can be overridden:
1042\begin{python}
1043@staticmethod
1044def _generate_next_value_( name, start, count, last_values ):
1045        return name
1046\end{python}
1047
1048There is no direct concept of restricting the enumerators in an enumeration \emph{instance} because dynamic typing changes the type.
1049\begin{python}
1050class RGB(Enum): Red = 1; Green = 2; Blue = 3
1051day : Week = Week.Tue;          $\C{\# type is Week}$
1052!day = RGB.Red!                         $\C{\# type is RGB}$
1053!day : Week = RGB.Red!          $\C{\# type is RGB}$
1054\end{python}
1055The enumerators are constants and cannot be reassigned.
1056Hence, while enumerators can be different types,
1057\begin{python}
1058class Diff(Enum): Int = 1; Float = 3.5; Str = "ABC"
1059\end{python}
1060it is not an ADT because the enumerator names are not constructors.
1061
1062An enumerator initialized with the same value is an alias and invisible at the enumeration level, \ie the alias is substituted for its aliases.
1063\begin{python}
1064class WeekD(Enum): Mon = 1; Tue = 2; Wed = 3; Thu = !10!; Fri = !10!; Sat = !10!; Sun = !10!
1065\end{python}
1066Here, the enumeration has only 4 enumerators and 3 aliases.
1067An alias is only visible by dropping down to the @class@ level and asking for class members.
1068Aliasing is prevented using the @unique@ decorator.
1069\begin{python}
1070!@unique!
1071class DupVal(Enum): One = 1; Two = 2; Three = !3!; Four = !3!
1072ValueError: duplicate values found in <enum 'DupVal'>: Four -> Three
1073\end{python}
1074
1075\begin{lrbox}{\myboxA}
1076\begin{python}
1077def by_position(enum_type, position):
1078        for index, value in enumerate(enum_type):
1079                if position == index: return value
1080        raise Exception("by_position out of range")
1081\end{python}
1082\end{lrbox}
1083There are bidirectional enumeration pseudo-functions for label and value, but there is no concept of access using ordering (position).\footnote{
1084There is an $O(N)$ mechanism to access an enumerator's value by position. \newline \usebox\myboxA}
1085\begin{cquote}
1086\setlength{\tabcolsep}{15pt}
1087\begin{tabular}{@{}ll@{}}
1088\begin{python}
1089Week.Thu.value == 4;
1090Week.Thu.name == "Thu";
1091\end{python}
1092&
1093\begin{python}
1094Week( 4 ) == Week.Thu
1095Week["Thu"].value == 4
1096\end{python}
1097\end{tabular}
1098\end{cquote}
1099@Enum@ only supports equality comparison between enumerator values.
1100There are multiple library extensions to @Enum@, \eg @OrderedEnum@ recipe class, adding relational operators @<@, @<=@, @>@, and @>=@.
1101
1102An enumeration \lstinline[language=python]{class} can have methods.
1103\begin{python}
1104class Week(!OrderedEnum!):
1105        Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7
1106        def !isWeekday(self)!:          # methods
1107                return Week(self.value) !<=! Week.Fri
1108        def !isWeekend(self)!:
1109                return Week.Sat !<=! Week(self.value) 
1110\end{python}
1111
1112An enumeration can be used in the @if@ and @switch@ statements but only for equality tests, unless extended to @OrderedEnum@.
1113\begin{cquote}
1114\setlength{\tabcolsep}{12pt}
1115\begin{tabular}{@{}ll@{}}
1116\begin{python}
1117if day <= Week.Fri :
1118        print( "weekday" );
1119
1120
1121
1122\end{python}
1123&
1124\begin{python}
1125match day:
1126        case Week.Mon | Week.Tue | Week.Wed | Week.Thu | Week.Fri:
1127                print( "weekday" );
1128        case Week.Sat | Week.Sun:
1129                print( "weekend" );
1130\end{python}
1131\end{tabular}
1132\end{cquote}
1133Looping is performed using the enumeration type or @islice@ from @itertools@ based on position.
1134\begin{python}
1135for day in !Week!:                                      $\C[2.25in]{\# Mon : 1 Tue : 2 Wed : 3 Thu : 4 Fri : 5 Sat : 6 Sun : 7}$
1136        print( day.name, ":", day.value, end=" " )
1137for day in !islice(Week, 0, 5)!:        $\C{\# Mon : 1 Tue : 2 Wed : 3 Thu : 4 Fri : 5}$
1138        print( day.name, ":", day.value, end=" " )
1139for day in !islice(Week, 5, 7)!:        $\C{\# Sat : 6 Sun : 7}$
1140        print( day.name, ":", day.value, end=" " )
1141for day in !islice(Week,0, 7, 2)!:      $\C{\# Mon : 1 Wed : 3 Fri : 5 Sun : 7}\CRT$
1142        print( day.name, ":", day.value, end=" " )
1143\end{python}
1144Iterating that includes alias names only (strings) is done using attribute @__members__@.
1145\begin{python}
1146for day in WeekD.__members__:
1147        print( day, ":", end=" " )
1148Mon : Tue : Wed : Thu : Fri : Sat : Sun
1149\end{python}
1150
1151Enumeration subclassing is allowed only if the enumeration base-class does not define any members.
1152\begin{python}
1153class WeekE(OrderedEnum): !pass!;  # no members
1154class WeekDay(WeekE): Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5;
1155class WeekEnd(WeekE): Sat = 6; Sun = 7
1156\end{python}
1157Here, type @WeekE@ is an abstract type because dynamic typing never uses it.
1158\begin{cquote}
1159\setlength{\tabcolsep}{25pt}
1160\begin{tabular}{@{}ll@{}}
1161\begin{python}
1162print( type(WeekE) )
1163day : WeekE = WeekDay.Fri       # set type
1164print( type(day), day )
1165day = WeekEnd.Sat                           # set type
1166print( type(day), day )
1167\end{python}
1168&
1169\begin{python}
1170<$class$ 'enum.EnumType'>
1171
1172<enum 'WeekDay'> WeekDay.Fri
1173
1174<enum 'WeekEnd'> WeekEnd.Sat
1175\end{python}
1176\end{tabular}
1177\end{cquote}
1178
1179There are a number of supplied enumeration base-types: @IntEnum@, @StrEnum@, @IntFalg@, @Flag@, which restrict the values in an enum using multi-inheritance.
1180@IntEnum@ is a subclass of @int@ and @Enum@, allowing enumerator comparison to @int@ and other enumerators of this type (like C enumerators).
1181@StrEnum@ is the same as @IntEnum@ but a subclass of the string type \lstinline[language=python]{str}.
1182@IntFlag@, is a restricted subclass of @int@ where the enumerators can be combined using the bitwise operators (@&@, @|@, @^@, @~@) and the result is an @IntFlag@ member.
1183@Flag@ is the same as @IntFlag@ but cannot be combined with, nor compared against, any other @Flag@ enumeration, nor @int@.
1184Auto increment for @IntFlag@ and @Flag@ is by powers of 2.
1185Enumerators that are combinations of single-bit enumerators are aliases and, hence, invisible.
1186The following is an example for @Flag@.
1187\begin{python}
1188class WeekF(Flag): Mon = 1; Tue = 2; Wed = 4; Thu = !auto()!; Fri = 16; Sat = 32; Sun = 64; \
1189          Weekday = Mon | Tue | Wed | Thu | Fri; \
1190          Weekend = Sat | Sun
1191print( f"0x{repr(WeekF.Weekday.value)} 0x{repr(WeekF.Weekend.value)}" )
11920x31 0x96
1193\end{python}
1194It is possible to enumerate through a @Flag@ enumerator (no aliases):
1195\begin{python}
1196for day in WeekF:
1197        print( f"{day.name}: {day.value}", end=" ")
1198Mon: 1 Tue: 2 Wed: 4 Thu: 8 Fri: 16 Sat: 32 Sun: 64 
1199\end{python}
1200and a combined alias enumerator for @Flag@.
1201\begin{cquote}
1202\setlength{\tabcolsep}{15pt}
1203\begin{tabular}{@{}ll@{}}
1204\begin{python}
1205weekday = WeekF.Weekday
1206for day in weekday:
1207        print( f"{day.name}:"
1208                   f" {day.value}", end=" " )
1209Mon: 1 Tue: 2 Wed: 4 Thu: 8 Fri: 16 
1210\end{python}
1211&
1212\begin{python}
1213weekend = WeekF.Weekend
1214for day in weekend:
1215        print( f"{day.name}:"
1216                   f" {day.value}", end=" " )
1217Sat: 32 Sun: 64 
1218\end{python}
1219\end{tabular}
1220\end{cquote}
1221
1222
1223\section{OCaml}
1224
1225% https://ocaml.org/docs/basic-data-types#enumerated-data-types
1226% https://dev.realworldocaml.org/runtime-memory-layout.html
1227
1228Like 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.
1229When @enum@ is an ADT, pattern matching is used to discriminate among the variant types.
1230\begin{cquote}
1231\setlength{\tabcolsep}{20pt}
1232\begin{tabular}{@{}l@{\hspace{35pt}}ll@{}}
1233\begin{ocaml}
1234type s = { i : int; j : int }
1235let sv : s = { i = 3; j = 5 }
1236@type@ adt =
1237        I of int |    $\C[1in]{// int}$
1238        F of float |  $\C{// float}$
1239        S of s        $\C{// struct}\CRT$
1240
1241
1242\end{ocaml}
1243&
1244\begin{ocaml}
1245let adtprt( adtv : adt ) =
1246        @match@ adtv with (* pattern matching *)
1247                I i -> printf "%d\n" i |
1248                F f -> printf "%g\n" f |
1249                S sv -> printf "%d %d\n" sv.i sv.j
1250let adtv : adt = I(3)       let _ = adtprt( adtv )
1251let adtv : adt = F(3.5)   let _ = adtprt( adtv )
1252let adtv : adt = S(sv)    let _ = adtprt( adtv )
1253\end{ocaml}
1254&
1255\begin{ocaml}
12563
12573.5
12583 5
1259
1260
1261
1262
1263
1264\end{ocaml}
1265\end{tabular}
1266\end{cquote}
1267% (Note, after an @adtv@'s type is know, the enumerator is inferred without qualification, \eg @I(3)@.)
1268
1269The type names are independent of the type value and mapped to an opaque, ascending, integral tag, starting from 0, supporting relational operators @<@, @<=@, @>@, and @>=@.
1270\begin{cquote}
1271\setlength{\tabcolsep}{10pt}
1272\begin{tabular}{@{}l@{\hspace{25pt}}ll@{}}
1273\begin{ocaml}
1274let silly( adtv : adt ) =
1275        if adtv <= F(3.5) then
1276                printf "<= F\n"
1277        else if adtv >= S(sv) then
1278                printf ">= S\n"
1279\end{ocaml}
1280&
1281\begin{ocaml}
1282let adtv : adt = I(3)       let _ = silly( adtv )
1283let adtv : adt = F(3.5)   let _ = silly( adtv )
1284let adtv : adt = S(sv)    let _ = silly( adtv )
1285
1286
1287\end{ocaml}
1288&
1289\begin{ocaml}
1290<= F
1291<= F
1292>= S
1293
1294
1295\end{ocaml}
1296\end{tabular}
1297\end{cquote}
1298In the example, type values must be specified (any appropriate values work) but ignored in the relational comparison of the type tag.
1299
1300An 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.
1301\begin{ocaml}
1302type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun
1303let day : week = Mon
1304\end{ocaml}
1305Since the type names are opaque, a type-tag value cannot be explicitly set nor can it have a type other than integral.
1306
1307As 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.
1308
1309While OCaml enumerators have an ordering following the definition order, they are not enumerable.
1310To 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).
1311However, as stated in the documentation, @enumerate@ PPX does not guarantee the order of the list.
1312PPX 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.
1313
1314New types can be formed as a composition of existing types.
1315\begin{ocaml}
1316type weekday = Mon | Tue | Wed | Thu | Fri
1317type weekend = Sat | Sun
1318type week = Weekday of weekday | Weekend of weekend
1319let day : week = Weekend Sun
1320\end{ocaml}
1321The type @week@ is the sum of @weekday@ and @weekend@, \ie @week@ has all the enumerators from the set @weekday@ and @weekend@.
1322The 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.
1323The wrapper is unwrapped with pattern matching.
1324\begin{cquote}
1325\begin{tabular}{@{}ll@{}}
1326\begin{ocaml}
1327type weekday = Mon | Tue | Wed | Thu | Fri
1328type weekend = Sat | Sun
1329type week = Weekday of weekday |
1330                                 Weekend of weekend
1331let wd : weekday = Mon
1332let _ = match wd with
1333        Mon -> printf "Mon " | _ -> ()
1334let we : weekend = Sun
1335let _ = match we with
1336        Sun -> printf "Sun " | _ -> ()
1337let day : week = Weekend Sun
1338let _ = match day with
1339        Weekend Sun -> printf "Sun\n" | _ -> ()
1340
1341\end{ocaml}
1342&
1343\begin{cfa}
1344enum() weekday { Mon, Tue, Wed, Thu, Fri };
1345enum() weekend { Sat, Sun };
1346enum() week { inline weekday, inline weekend };
1347int main() {
1348        weekday wd = Mon;
1349
1350        printf( "%s ", label( wd ) );
1351        weekend we = Sun;
1352
1353        printf( "%s ", label( we ) );
1354        week day = Sun;
1355
1356        printf( "%s\n", label( day ) );
1357}
1358\end{cfa}
1359\\
1360\begin{cfa}
1361Mon Sun Sun
1362\end{cfa}
1363\end{tabular}
1364\end{cquote}
1365
1366%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1367
1368\begin{comment}
1369Date: Wed, 13 Mar 2024 10:52:34 -0400
1370Subject: Re: OCaml
1371To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>
1372From: Gregor Richards <gregor.richards@uwaterloo.ca>
1373
1374On 3/12/24 18:34, Peter A. Buhr wrote:
1375> Gregor, attached is a section Jiada wrote on OCaml (1-page).
1376> Does it reflect our discussion about functional languages and enumerations?
1377
1378Yeah, I think so. The most important part, i.e., that once they're
1379parameterized they're not really enumerations at all, is covered clearly
1380enough.
1381
1382A couple quibbles:
1383
1384<<a list of untyped tags>>
1385
1386This is true, but leaking implementation details. These are nullary datatype
1387constructors. Indeed, you later talk about "tagged variants", which are really
1388just parameterized variants, using the term "tag" differently, confusing the
1389term "tag" further.
1390
1391<<Because week is a summation of values Mon to Sun, it is a sum type in
1392turns of the functional-programming paradigm>>
1393
1394It is a *union* of values and is a *union* type.
1395
1396With valediction,
1397  - Gregor Richards
1398
1399
1400Date: Thu, 14 Mar 2024 21:45:52 -0400
1401Subject: Re: OCaml "enums" do come with ordering
1402To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>
1403From: Gregor Richards <gregor.richards@uwaterloo.ca>
1404
1405On 3/14/24 21:30, Peter A. Buhr wrote:
1406> I've marked 3 places with your name to shows places with enum ordering.
1407>
1408> open Printf
1409> type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun
1410> let day : week = Mon
1411> let take_class( d : week ) =
1412>       if d <= Fri then                                (* Gregor *)
1413>               printf "week\n"
1414>       else if d >= Sat then                   (* Gregor *)
1415>               printf "weekend\n";
1416>       match d with
1417>               Mon | Wed -> printf "CS442\n" |
1418>               Tue | Thu -> printf "CS343\n" |
1419>               Fri -> printf "Tutorial\n" |
1420>               _ -> printf "Take a break\n"
1421>
1422> let _ = take_class( Mon ); take_class( Sat );
1423>
1424> type colour = Red | Green of string | Blue of int * float
1425> let c = Red
1426> let _ = match c with Red -> printf "Red, "
1427> let c = Green( "abc" )
1428> let _ = match c with Green g -> printf "%s, " g
1429> let c = Blue( 1, 1.5 )
1430> let _ = match c with Blue( i, f ) -> printf "%d %g\n" i f
1431>
1432> let check_colour(c: colour): string =
1433>       if c < Green( "xyz" ) then              (* Gregor *)
1434>               printf "green\n";
1435>       match c with
1436>               Red -> "Red" |
1437>               Green g -> g |
1438>               Blue(i, f) -> string_of_int i ^ string_of_float f
1439> let _ = check_colour( Red ); check_colour( Green( "xyz" ) );
1440>
1441> type stringList = Empty | Pair of string * stringList
1442> let rec len_of_string_list(l: stringList): int =
1443>       match l with
1444>               Empty -> 0 |
1445>               Pair(_ , r) -> 1 + len_of_string_list r
1446>
1447> let _ = for i = 1 to 10 do
1448>       printf "%d, " i
1449> done
1450>
1451> (* Local Variables: *)
1452> (* tab-width: 4 *)
1453> (* compile-command: "ocaml test.ml" *)
1454> (* End: *)
1455
1456My functional-language familiarity is far more with Haskell than OCaml.  I
1457mostly view OCaml through a lens of "it's Haskell but with cheating".  Haskell
1458"enums" (ADTs) aren't ordered unless you specifically and manually put them in
1459the Ord typeclass by defining the comparators.  Apparently, OCaml has some
1460other rule, which I would guess is something like "sort by tag then by order of
1461parameter". Having a default behavior for comparators is *bizarre*; my guess
1462would be that it gained this behavior in its flirtation with object
1463orientation, but that's just a guess (and irrelevant).
1464
1465This gives a total order, but not enumerability (which would still be
1466effectively impossible or even meaningless since enums are just a special case
1467of ADTs).
1468
1469With valediction,
1470  - Gregor Richards
1471
1472Date: Wed, 20 Mar 2024 18:16:44 -0400
1473Subject: Re:
1474To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>
1475From: Gregor Richards <gregor.richards@uwaterloo.ca>
1476
1477
1478On 3/20/24 17:26, Peter A. Buhr wrote:
1479> Gregor, everyone at this end would like a definition of "enumerability". Can
1480> you formulate one?
1481
1482According to the OED (emphasis added to the meaning I'm after):
1483
1484enumerate (verb, transitive). To count, ascertain the number of; **more
1485usually, to mention (a number of things or persons) separately, as if for the
1486purpose of counting**; to specify as in a list or catalogue.
1487
1488With C enums, if you know the lowest and highest value, you can simply loop
1489over them in a for loop (this is, of course, why so many enums come with an
1490ENUM_WHATEVER_LAST value). But, I would be hesitant to use the word "loop" to
1491describe enumerability, since in functional languages, you would recurse for
1492such a purpose.
1493
1494In Haskell, in order to do something with every member of an "enumeration", you
1495would have to explicitly list them all. The type system will help a bit since
1496it knows if you haven't listed them all, but you would have to statically have
1497every element in the enumeration.  If somebody added new elements to the
1498enumeration later, your code to enumerate over them would no longer work
1499correctly, because you can't simply say "for each member of this enumeration do
1500X". In Haskell that's because there aren't actually enumerations; what they use
1501as enumerations are a degenerate form of algebraic datatypes, and ADTs are
1502certainly not enumerable. In OCaml, you've demonstrated that they impose
1503comparability, but I would still assume that you can't make a loop over every
1504member of an enumeration. (But, who knows!)
1505
1506Since that's literally what "enumerate" means, it seems like a rather important
1507property for enumerations to have ;)
1508
1509With valediction,
1510  - Gregor Richards
1511
1512
1513From: Andrew James Beach <ajbeach@uwaterloo.ca>
1514To: Gregor Richards <gregor.richards@uwaterloo.ca>, Peter Buhr <pabuhr@uwaterloo.ca>
1515CC: Michael Leslie Brooks <mlbrooks@uwaterloo.ca>, Fangren Yu <f37yu@uwaterloo.ca>,
1516        Jiada Liang <j82liang@uwaterloo.ca>
1517Subject: Re: Re:
1518Date: Thu, 21 Mar 2024 14:26:36 +0000
1519
1520Does this mean that not all enum declarations in C create enumerations? If you
1521declare an enumeration like:
1522
1523enum Example {
1524        Label,
1525        Name = 10,
1526        Tag = 3,
1527};
1528
1529I don't think there is any way to enumerate (iterate, loop, recurse) over these
1530values without listing all of them.
1531
1532
1533Date: Thu, 21 Mar 2024 10:31:49 -0400
1534Subject: Re:
1535To: Andrew James Beach <ajbeach@uwaterloo.ca>, Peter Buhr <pabuhr@uwaterloo.ca>
1536CC: Michael Leslie Brooks <mlbrooks@uwaterloo.ca>, Fangren Yu <f37yu@uwaterloo.ca>,
1537    Jiada Liang <j82liang@uwaterloo.ca>
1538From: Gregor Richards <gregor.richards@uwaterloo.ca>
1539
1540I consider this conclusion reasonable. C enums can be nothing more than const
1541ints, and if used in that way, I personally wouldn't consider them as
1542enumerations in any meaningful sense, particularly since the type checker
1543essentially does nothing for you there. Then they're a way of writing consts
1544repeatedly with some textual indicator that these definitions are related; more
1545namespace, less enum.
1546
1547When somebody writes bitfield members as an enum, is that *really* an
1548enumeration, or just a use of the syntax for enums to keep related definitions
1549together?
1550
1551With valediction,
1552  - Gregor Richards
1553
1554
1555Date: Tue, 16 Apr 2024 11:04:51 -0400
1556Subject: Re: C unnamed enumeration
1557To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>
1558CC: <ajbeach@uwaterloo.ca>, <j82liang@uwaterloo.ca>, <mlbrooks@uwaterloo.ca>,
1559        <f37yu@uwaterloo.ca>
1560From: Gregor Richards <gregor.richards@uwaterloo.ca>
1561
1562On 4/16/24 09:55, Peter A. Buhr wrote:
1563> So what is a variant? Is it a set of tag names, which might be a union or is it
1564> a union, which might have tag names?
1565
1566Your tagless variant bears no resemblance to variants in any functional
1567programming language. A variant is a tag AND a union. You might not need to put
1568anything in the union, in which case it's a pointless union, but the named tag
1569is absolutely mandatory. That's the thing that varies.
1570
1571I was unaware of std::variant. As far as functional languages are concerned,
1572std::variant IS NOT A VARIANT. Perhaps it would be best to use the term ADT for
1573the functional language concept, because that term has no other meanings.
1574
1575An ADT cannot not have a named tag. That's meaningless. The tag is the data
1576constructor, which is the thing you actually define when you define an ADT. It
1577is strictly the union that's optional.
1578
1579With valediction,
1580  - Gregor Richards
1581\end{comment}
1582
1583
1584\section{Comparison}
1585
1586\VRef[Table]{t:FeatureLanguageComparison} shows a comparison of enumeration features and programming languages with the explaination of categories below.
1587The features are high-level and may not capture nuances within a particular language.
1588
1589\begin{table}
1590\caption{Enumeration Feature / Language Comparison}
1591\label{t:FeatureLanguageComparison}
1592\small
1593\setlength{\tabcolsep}{3pt}
1594\newcommand{\CM}{\checkmark}
1595\begin{tabular}{r|c|c|c|c|c|c|c|c|c|c|c|c|c}
1596                                &Pascal & Ada                   &\Csharp   & OCaml  & Java      &Golang   & Rust                & Swift                 & Python& C             & \CC   & \CFA  \\
1597\hline
1598enum                    &Dialect& \CM                   & \CM      & ADT    & \CM   & @const@ &ADT/\CM      &ADT/\CM            & \CM   &\CM    &\CM   &\CM\\
1599\hline
1600\hline
1601opaque                  & \CM    &                              &                  & \CM    & \CM   &             & \CM         & \CM                   &               &               &               & \CM   \\
1602\hline
1603typed                   & Int    & Int                  & Int     & H     & U     & H       & U/H         & U/H           & H       & Int       & Int   & U     \\
1604\hline
1605safety          & \CM   & \CM                   &          & \CM        & \CM   &                 & \CM                 & \CM                   &               &               & \CM   & \CM   \\
1606\hline
1607posn ordered    & Implied & Implied     &          & \CM    &       &             &                         &                   &       &           &       & \CM       \\
1608\hline
1609unique values   & \CM   & \CM           &           &\CM        &       &      &                            & \CM               &       &           &       &     \\
1610\hline
1611auto-init               & \CM   & all or none   & \CM      & N/A &       & \CM     & \CM            & \CM               & \CM   & \CM   & \CM   & \CM   \\
1612\hline
1613(Un)Scoped              & U     & U                     & S        & S      & S         & U       & S               & S                         & S     & U             & U/S   & U/S   \\
1614\hline
1615overload                &               & \CM                   &              &            &      &              &                 &                       &      &            &       & \CM   \\
1616\hline
1617loop                    & \CM   & \CM                   &                  &            &               &                 &                         &                   & \CM   &               &               & \CM   \\
1618\hline
1619arr. dim.               & \CM   & \CM           &                  &              &                 &           &                 &                         &            &      &               & \CM \\
1620\hline
1621subset                  & \CM   & \CM                   &         &      &              &                 &                         &                   &               &               &               & \CM   \\
1622\hline
1623superset                &               &                               &                 & \CM   &                 &             &\CM        &\CM            &         &               &               & \CM   \\
1624\end{tabular}
1625\end{table}
1626
1627\begin{enumerate}
1628\item opaque: an enumerator cannot be used as its underlying representation or implemented in terms of an ADT.
1629\item typed: H $\Rightarrow$ heterogeneous, \ie enumerator values may be different types. \\
1630U $\Rightarrow$ homogenous, \ie enumerator values have the same type.
1631\item safety: An enumeration variable can only hold a value from its defined enumerators.
1632\item posn ordered: enumerators have defined ordering based on enumerator declaration order.
1633Position ordered is implied if the enumerator values must be strictly increasingly.
1634\item unique value: enumerators must have a unique value.
1635\item auto-init: Values are auto-initializable by language specification. \\
1636It is not appliable to OCaml because OCaml enumeration has unit type.
1637\item (Un)Scoped: U $\Rightarrow$ enumerators are projected into the containing scope.
1638S $\Rightarrow$ enumerators are contained in the enumeration scope and require qualification.
1639\item overload: An enumerator label can be used without type qualification in a context where multiple enumerations have defined the label.
1640\item loop: Enumerate without the need to convert an enumeration to another data structure.
1641\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).
1642\item subset: Name a subset of enumerators as a new type.
1643\item superset: Create a new enumeration that contains all enumerators from pre-defined enumerations.
1644\end{enumerate}
Note: See TracBrowser for help on using the repository browser.