Changeset 7d9a805b


Ignore:
Timestamp:
Mar 21, 2024, 9:34:28 PM (3 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
6394ac6
Parents:
0139351
Message:

more proofreading for enumerations

Location:
doc/theses/jiada_liang_MMath
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/jiada_liang_MMath/CFAenum.tex

    r0139351 r7d9a805b  
    1 \chapter{\CFA-Style Enum}
    2 
    3 
    4 \CFA supports C-Style enumeration using the same syntax and semantics for backwards compatibility.
     1\chapter{\CFA Enumeration}
     2
     3
     4\CFA supports C enumeration using the same syntax and semantics for backwards compatibility.
    55\CFA also extends C-Style enumeration by adding a number of new features that bring enumerations inline with other modern programming languages.
    66
     
    1616Finally, qualification is provided to disambiguate any ambiguous situations.
    1717\begin{cfa}
    18 enum C1 { First, Second, Third, Fourth };
    19 enum C2 { @Fourth@, @Third@, @Second@, @First@ };
    20 C1 p() { return Third; }                                $\C{// correctly resolved duplicate names}$
    21 C2 p() { return Fourth; }
     18enum E1 { First, Second, Third, Fourth };
     19enum E2 { @Fourth@, @Third@, @Second@, @First@ };
     20E1 p() { return Third; }                                $\C{// correctly resolved duplicate names}$
     21E2 p() { return Fourth; }
    2222void foo() {
    23         C1 e1 = First;   C2 e2 = First;
     23        E1 e1 = First;   E2 e2 = First;
    2424        e1 = Second;   e2 = Second;
    2525        e1 = p();   e2 = p();                           $\C{// correctly resolved function call}$
    26         int i = @C1.@First + @C2.@First;        $\C{// ambiguous without qualification}$
    27 }
    28 \end{cfa}
    29 \CFA overloading allows programmers to use the most meaningful names without fear of unresolvable clashes from included files, which are correctable with qualification.
     26        int i = @E1.@First + @E2.@First;        $\C{// disambiguate with qualification}$
     27        int j = @(E1)@First + @(E2)@First;      $\C{// disambiguate with cast}$
     28}
     29\end{cfa}
     30\CFA overloading allows programmers to use the most meaningful names without fear of name clashes from include files.
     31Either the type system implicitly disambiguates or the programmer explicitly disambiguates using qualification or casting.
    3032
    3133
     
    3436An enumeration can be scoped, so the enumerator constants are not projected into the enclosing scope, using @'!'@.
    3537\begin{cfa}
    36 enum Weekday @!@ { /* as above */ };
    37 enum( char * ) Names @!@ { /* as above */ };
     38enum Weekday @!@ { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun };
     39enum RGB @!@ { Red, Green, Blue };
    3840\end{cfa}
    3941Now the enumerators \emph{must} be qualified with the associated enumeration.
    4042\begin{cfa}
    41 Weekday weekday = @Weekday@.Monday;
    42 Names names = @Names.@Fred;
    43 names = @Names.@Jane;
     43Weekday weekday = @Weekday@.Mon;
     44weekday = @Weekday@.Sat;
     45RGB rgb = RGB.Red;
     46rgb = RGB.Blue;
    4447\end{cfa}
    4548It is possible to toggle back to unscoping using the \CFA @with@ clause/statement (see also \CC \lstinline[language=c++]{using enum} in Section~\ref{s:C++RelatedWork}).
    4649\begin{cfa}
    47 Weekday weekday;
    48 with ( @Weekday@, @Names@ ) {                   $\C{// type names}$
    49          Names names = @Fred@;
    50          names = @Jane@;
    51          weekday = Saturday;
    52 }
    53 \end{cfa}
    54 As in Section~\ref{s:EnumeratorNameResolution}, opening multiple unscoped enumerations can result in duplicate enumeration names, but \CFA type resolution and falling back to explicit qualification handles name resolution.
     50with ( @Weekday@, @RGB@ ) {                     $\C{// type names}$
     51         weekday = @Sun@;                               $\C{// no qualification}$
     52         rgb = @Green@;
     53}
     54\end{cfa}
     55As in Section~\ref{s:EnumeratorNameResolution}, opening multiple unscoped enumerations can result in duplicate enumeration names, but \CFA implicit type resolution and explicit qualification/casting handles name resolution.
    5556
    5657\section{Enumerator Typing}
     
    8081\begin{cfa}
    8182// integral
    82         enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$' };
     83        enum( @char@ ) Currency { Dollar = '$\textdollar$', Cent = '$\textcent$', Yen = '$\textyen$', Pound = '$\textsterling$', Euro = 'E' };
    8384        enum( @signed char@ ) srgb { Red = -1, Green = 0, Blue = 1 };
    8485        enum( @long long int@ ) BigNum { X = 123_456_789_012_345,  Y = 345_012_789_456_123 };
     
    8788        enum( @_Complex@ ) Plane { X = 1.5+3.4i, Y = 7+3i, Z = 0+0.5i };
    8889// pointer
    89         enum( @char *@ ) Names { Fred = "FRED", Mary = "MARY", Jane = "JANE" };
     90        enum( @const char *@ ) Name { Fred = "FRED", Mary = "MARY", Jane = "JANE" };
    9091        int i, j, k;
    9192        enum( @int *@ ) ptr { I = &i,  J = &j,  K = &k };
     
    9899// aggregate
    99100        struct Person { char * name; int age, height; };
    100 @***@enum( @Person@ ) friends { @Liz@ = { "ELIZABETH", 22, 170 }, @Beth@ = Liz, Jon = { "JONATHAN", 35, 190 } };
     101@***@enum( @Person@ ) friends { @Liz@ = { "ELIZABETH", 22, 170 }, @Beth@ = Liz,
     102                                                                                        Jon = { "JONATHAN", 35, 190 } };
    101103\end{cfa}
    102104\caption{Enumerator Typing}
     
    140142\begin{cfa}
    141143enum() Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND };
    142 @***@Mode iomode = O_RDONLY;
    143 bool b = iomode == O_RDONLY || iomode < O_APPEND;
    144 int i = iomode;                                                 $\C{\color{red}// disallowed}$
     144Mode iomode = O_RDONLY;
     145bool b = iomode == O_RDONLY || iomode < O_APPEND; $\C{// ordering}$
     146@***@@int i = iomode;@                                                  $\C{// disallow conversion to int}$
    145147\end{cfa}
    146148
     
    149151If follows from enumerator typing that the enumerator type can be another enumerator.
    150152\begin{cfa}
    151 enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$' };
    152 enum( @Currency@ ) Europe { Euro = Currency.Euro, Pound = Currency.Pound }; // intersection
     153enum( @char@ ) Currency { Dollar = '$\textdollar$', Cent = '$\textcent$', Yen = '$\textyen$', Pound = '$\textsterling$', Euro = 'E' };
     154enum( Currency ) Europe { Euro = Currency.Euro, Pound = Currency.Pound };
    153155enum( char ) Letter { A = 'A',  B = 'B', C = 'C', ..., Z = 'Z' };
    154156enum( @Letter@ ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // intersection
     
    158160\begin{cfa}
    159161Letter letter = A;
    160 @***@Greak greek = Beta;
    161 letter = Beta;                                                  $\C{// allowed, letter == B}$
    162 greek = A;                                                              $\C{\color{red}// disallowed}$
     162Greak greek = Beta;
     163letter = Beta;                                                  $\C{// allowed, greek == B}$
     164@greek = A;@                                                    $\C{// disallowed}$
    163165\end{cfa}
    164166
     
    277279p(variable_d); // 3
    278280\end{cfa}
     281
     282
     283\section{Planet Example}
     284
     285\VRef[Figure]{f:PlanetExample} shows an archetypal enumeration example illustrating all of the \CFA enumeration features.
     286Enumeration @Planet@ is a typed enumeration of type @MR@.
     287Each of the planet enumerators is initialized to a specific mass/radius, @MR@, value.
     288The unnamed enumeration projects the gravitational-constant enumerator @G@.
     289The program main iterates through the planets computing the weight on each planet for a given earth weight.
     290
     291\begin{figure}
     292\begin{cfa}
     293struct MR { double mass, radius; };
     294enum( MR ) Planet {
     295        //                           mass          radius
     296        MERCURY = { 3.303_E23, 2.4397_E6 },
     297        VENUS       = { 4.869_E24, 6.0518_E6 },
     298        EARTH       = { 5.976_E24, 6.3781_E6 },
     299        MARS         = { 6.421_E23, 3.3972_E6 },
     300        JUPITER    = { 1.898_E27, 7.1492_E7 },
     301        SATURN     = { 5.688_E26, 6.0268_E7 },
     302        URANUS    = { 8.686_E25, 2.5559_E7 },
     303        NEPTUNE  = { 1.024_E26, 2.4746_E7 },
     304};
     305enum( double ) { G = 6.6743E-11 }; // universal gravitational constant (m3 kg-1 s-2)
     306
     307static double surfaceGravity( Planet p ) with( p ) {
     308        return G * mass / ( radius * radius );
     309}
     310static double surfaceWeight( Planet p, double otherMass ) {
     311        return otherMass * surfaceGravity( p );
     312}
     313int main( int argc, char * argv[] ) {
     314        if ( argc != 2 ) exit | "Usage: " | argv[0] | "earth-weight";
     315        double earthWeight = convert( argv[1] );
     316        double mass = earthWeight / surfaceGravity( EARTH );
     317        for ( p; Planet ) {
     318                sout | "Your weight on" | labelE(p) | "is" | surfaceWeight( p, mass );
     319        }
     320}
     321\end{cfa}
     322\caption{Planet Example}
     323\label{f:PlanetExample}
     324\end{figure}
  • doc/theses/jiada_liang_MMath/background.tex

    r0139351 r7d9a805b  
    11\chapter{Background}
     2\lstnewenvironment{clang}[1][]{\lstset{language=[ANSI]C,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
     3
     4\CFA is a backwards-compatible extension of the C programming language.
     5Therefore, it must support C-style enumerations and any enumeration extensions must be intuitive to C programmers both in syntax and semantics.
     6
     7It is common for C programmers to ``believe'' there are three equivalent forms of named constants.
     8\begin{clang}
     9#define Mon 0
     10static const int Mon = 0;
     11enum { Mon };
     12\end{clang}
     13\begin{enumerate}[leftmargin=*]
     14\item
     15For @#define@, the programmer has to explicitly manage the constant name and value.
     16Furthermore, these C preprocessor macro names are outside of the C type-system, and hence cannot be overloaded, and can incorrectly change random text in a program.
     17\item
     18The same explicit management is true for the @const@ declaration, and the @const@ variable cannot appear in constant-expression locations, like @case@ labels, array dimensions,\footnote{
     19C allows variable-length array-declarations (VLA), so this case does work, but it fails in \CC, which does not support VLAs, unless it is \lstinline{g++}.} immediate operands of assembler instructions, and occupy storage.
     20\begin{clang}
     21$\$$ nm test.o
     220000000000000018 r Mon
     23\end{clang}
     24\item
     25Only the @enum@ form is managed by the compiler, is part of the language type-system, and works in all C constant-expression locations.
     26\end{enumerate}
    227
    328
    4 \section{C-Style Enum}
     29\section{C \lstinline{const}}
    530
    6 The C-Style enumeration has the following syntax and semantics.
    7 \begin{cfa}
    8 enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday };
    9 \end{cfa}
     31As noted, C has the equivalent of Pascal typed @const@ declarations \see{\VRef{s:Pascal}}, with static and dynamic initialization.
     32\begin{clang}
     33static const int one = 0 + 1;                   $\C{// static intialization}$
     34static const void * NIL = NULL;
     35static const double PI = 3.14159;
     36static const char Plus = '+';
     37static const char * Fred = "Fred";
     38static const int Mon = 0, Tue = Mon + 1, Wed = Tue + 1, Thu = Wed + 1, Fri = Thu + 1,
     39                                        Sat = Fri + 1, Sun = Sat + 1;
     40void foo() {
     41        const int r = random();                         $\C{// dynamic intialization}$
     42        int sa[Sun];                                            $\C{// VLA, local scope only}$
     43}
     44\end{clang}
     45Statically initialized identifiers may appear in any constant-expression context, \eg @case@.
     46Dynamically initialized identifiers may appear as array dimensions in @g++@, which allows variable-sized arrays.
     47
     48
     49\section{C Enumeration}
     50
     51The C enumeration has the following syntax and semantics.
     52\begin{clang}
     53enum Weekday { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun, };
     54\end{clang}
    1055Enumerators without an explicitly designated constant value are \Newterm{auto-initialized} by the compiler: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@.
    11 For example, @Monday@ to @Wednesday@ are implicitly assigned with constants @0@--@2@, @Thursday@ is explicitly set to constant @10@, and @Friday@ to @Sunday@ are implicitly assigned with constants @11@--@13@.
     56For example, @Mon@ to @Wed@ are implicitly assigned with constants @0@--@2@, @Thu@ is explicitly set to constant @10@, and @Fri@ to @Sun@ are implicitly assigned with constants @11@--@13@.
    1257Initialization may occur in any order.
    13 \begin{cfa}
    14 enum Weekday { Thursday@ = 10@, Friday, Saturday, Sunday, Monday@ = 0@, Tuesday, Wednesday };
    15 \end{cfa}
     58\begin{clang}
     59enum Weekday { Thu@ = 10@, Fri, Sat, Sun, Mon@ = 0@, Tue, Wed };
     60\end{clang}
    1661Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma.
    17 \begin{cfa}
     62\begin{clang}
    1863enum Weekday {
    19         Thursday = 10, Friday, Saturday, Sunday,
    20         Monday = 0, Tuesday, Wednesday@,@ // terminating comma
     64        Thu = 10, Fri, Sat, Sun,
     65        Mon = 0, Tue, Wed@,@ // terminating comma
    2166};
    22 \end{cfa}
     67\end{clang}
    2368This feature allow enumerator lines to be interchanged without moving a comma.\footnote{
    2469A terminating comma appears in other C syntax, \eg the initializer list.}
     
    2873In practice, since integral constants are used, which have type @int@ (unless qualified with a size suffix), C uses @int@ as the underlying type for enumeration variables.
    2974Finally, there is an implicit bidirectional conversion between an enumeration and its integral type.
    30 \begin{cfa}
     75\begin{clang}
    3176{
    3277        enum Weekday { /* as above */ };        $\C{// enumerators implicitly projected into local scope}$
    33         Weekday weekday = Monday;                       $\C{// weekday == 0}$
    34         weekday = Friday;                                       $\C{// weekday == 11}$
    35         int i = Sunday;                                         $\C{// implicit conversion to int, i == 13}$
     78        Weekday weekday = Mon                        $\C{// weekday == 0}$
     79        weekday = Fri                                        $\C{// weekday == 11}$
     80        int i = Sun;                                            $\C{// implicit conversion to int, i == 13}$
    3681        weekday = 10000;                                        $\C{// UNDEFINED! implicit conversion to Weekday}$
    3782}
    38 int j = Wednesday;                                              $\C{// ERROR! Wednesday is not declared in this scope}$
    39 \end{cfa}
     83int j = Wed;                                                    $\C{// ERROR! Wed is not declared in this scope}$
     84\end{clang}
    4085The implicit conversion from @int@ to an enumeration type is an unnecessary source of error.
    41 
    42 It is common for C programmers to ``believe'' there are 3 equivalent forms of constant enumeration.
    43 \begin{cfa}
    44 #define Monday 0
    45 static const int Monday = 0;
    46 enum { Monday };
    47 \end{cfa}
    48 For @#define@, the programmer has to play compiler and explicitly manage the enumeration values;
    49 furthermore, these are independent constants outside of any language type mechanism.
    50 The same explicit management is true for @const@ declarations, and the @const@ variable cannot appear in constant-expression locations, like @case@ labels, array dimensions,\footnote{
    51 C allows variable-length array-declarations (VLA), so this case does work, but it fails in \CC, which does not support VLAs, unless it is \lstinline{g++}.} and immediate operands of assembler instructions.
    52 Only the @enum@ form is managed by the compiler, is part of the language type-system, and works in all C constant-expression locations.
  • doc/theses/jiada_liang_MMath/implementation.tex

    r0139351 r7d9a805b  
    548548\begin{cfa}
    549549enum(int) Weekday {
    550         Monday=10, Tuesday, ...
     550        Mon = 10, Tue, ...
    551551};
    552552
  • doc/theses/jiada_liang_MMath/intro.tex

    r0139351 r7d9a805b  
    44Naming is also commonly used to represent many other numerical phenomenon, such as days of the week, months of a year, floors of a building (basement), specific times (noon, New Years).
    55Many programming languages capture this important software engineering capability through a mechanism called an \Newterm{enumeration}.
    6 An enumeration is similar to other programming-language types by providing a set of constrained values, but adds the ability to name \emph{all} the values in its set.
     6An enumeration is similar to other programming-language types by providing a set of constrained values, but adds the ability to name \emph{all} the values in the set.
    77Note, all enumeration names must be unique but different names can represent the same value (eight note, quaver), which are synonyms.
    88
     
    1111
    1212Fundamentally, all enumeration systems have an \Newterm{enumeration} type with an associated set of \Newterm{enumerator} names.
    13 An enumeration has three universal attributes, \Newterm{position}, \Newterm{label}, and \Newterm{value}, as shown by this representative enumeration, where position and value can be different.
     13An enumeration has three universal attributes, \Newterm{label}, \Newterm{position}, and \Newterm{value}, as shown by this representative enumeration, where position and value can be different.
    1414\begin{cquote}
    1515\small\sf\setlength{\tabcolsep}{3pt}
     
    1717\it\color{red}enumeration & \multicolumn{7}{c}{\it\color{red}enumerators}       \\
    1818$\downarrow$\hspace*{25pt} & \multicolumn{7}{c}{$\downarrow$}                           \\
    19 @enum@ Weekday \{                               & Monday,       & Tuesday,      & Wednesday,    & Thursday,& Friday,    & Saturday,     & Sunday \}; \\
    20 \it\color{red}position                  & 0                     & 1                     & 2                             & 3                             & 4                     & 5                     & 6                     \\
    21 \it\color{red}label                             & Monday        & Tuesday       & Wednesday             & Thursday              & Friday        & Saturday      & Sunday        \\
    22 \it\color{red}value                             & 0                     & 1                     & 2                             & 3                             & 4                     & 5             & 6
     19@enum@ Weekday \{                               & Mon,  & Tue,  & Wed,  & Thu,  & Fri,  & Sat,  & Sun \};       \\
     20\it\color{red}label                             & Mon   & Tue   & Wed   & Thu   & Fri   & Sat   & Sun           \\
     21\it\color{red}position                  & 0             & 1             & 2             & 3             & 4             & 5             & 6                     \\
     22\it\color{red}value                             & 0             & 1             & 2             & 3             & 4             & 5             & 6
    2323\end{tabular}
    2424\end{cquote}
    25 Here, the \Newterm{enumeration} @Weekday@ defines the ordered \Newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@.
    26 By convention, the successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@, independent of the associated enumerator constant values.
    27 Because an enumerator is a constant, it cannot appear in a mutable context, \eg @Mon = Sun@ is meaningless, and an enumerator has no address, it is an \Newterm{rvalue}\footnote{
    28 The term rvalue defines an expression that can only appear on the right-hand side of an assignment.}.
     25Here, the \Newterm{enumeration} @Weekday@ defines the ordered \Newterm{enumerator}s @Mon@, @Tue@, @Wed@, @Thu@, @Fri@, @Sat@ and @Sun@.
     26By convention, the successor of @Tue@ is @Mon@ and the predecessor of @Tue@ is @Wed@, independent of the associated enumerator constant values, implying an ordering among the enumerators.
     27As well, the value can be explicitly set so it is different from the position.
     28Because an enumerator is a constant, it cannot appear in a mutable context, \eg @Mon = Sun@ is meaningless, and an enumerator has no address, \ie it is an \Newterm{rvalue}\footnote{
     29The term rvalue defines an expression that can only appear on the right-hand side of an assignment expression.}.
     30
     31On the surface, enumerations seem like a simple type.
     32However, when extended with features available in other language types, enumerations become a complex.
     33
     34The goal of this work is to to extend the simple and unsafe enumeration type in the C programming-language into a sophisticated and safe type in the \CFA programming-language, while maintain backwards compatibility with C.
    2935
    3036\section{Contributions}
     37
  • doc/theses/jiada_liang_MMath/relatedwork.tex

    r0139351 r7d9a805b  
    22\label{s:RelatedWork}
    33
     4\begin{comment}
    45An algebraic data type (ADT) can be viewed as a recursive sum of product types.
    56A sum type lists values as members.
     
    1516Enumerated types are a special case of product/sum types with non-mutable fields, \ie initialized (constructed) once at the type's declaration, possible restricted to compile-time initialization.
    1617Values of algebraic types are access by subscripting, field qualification, or type (pattern) matching.
     18\end{comment}
    1719
    1820Enumeration types 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}, Java~\cite{Java}, Modula-3~\cite{Modula-3}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}.
     
    2022
    2123\section{Pascal}
     24\label{s:Pascal}
    2225\lstnewenvironment{pascal}[1][]{\lstset{language=pascal,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
    2326
     
    2730                 PI = 3.14159;   Plus = '+';   Fred = 'Fred';
    2831\end{pascal}
    29 Here, there is no enumeration because there is no specific type (pseudo enumeration).
     32This mechanism is not an enumeration because there is no specific type (pseudo enumeration).
    3033Hence, there is no notion of a (possibly ordered) set, modulo the \lstinline[language=pascal]{set of} type.
    3134The type of each constant name (enumerator) is inferred from the constant-expression type.
     
    8184with Ada.Text_IO; use Ada.Text_IO;
    8285procedure test is
    83    type RGB is ( @Red@, Green, Blue );
    84    type Traffic_Light is ( @Red@, Yellow, Green );         -- overload
    85    procedure @Red@( Colour : RGB ) is begin            -- overload
    86        Put_Line( "Colour is " & RGB'Image( Colour ) );
    87    end Red;
    88    procedure @Red@( TL : Traffic_Light ) is begin       -- overload
    89        Put_Line( "Light is " & Traffic_Light'Image( TL ) );
    90    end Red;
     86        type RGB is ( @Red@, Green, Blue );
     87        type Traffic_Light is ( @Red@, Yellow, Green );         -- overload
     88        procedure @Red@( Colour : RGB ) is begin            -- overload
     89                Put_Line( "Colour is " & RGB'Image( Colour ) );
     90        end Red;
     91        procedure @Red@( TL : Traffic_Light ) is begin       -- overload
     92                Put_Line( "Light is " & Traffic_Light'Image( TL ) );
     93        end Red;
    9194begin
    92     @Red@( Blue );                               -- RGB
    93     @Red@( Yellow );                            -- Traffic_Light
    94     @Red@( @RGB'(Red)@ );               -- ambiguous without cast
     95        @Red@( Blue );                           -- RGB
     96        @Red@( Yellow );                                -- Traffic_Light
     97        @Red@( @RGB'(Red)@ );           -- ambiguous without cast
    9598end test;
    9699\end{ada}
     
    224227\lstnewenvironment{c++}[1][]{\lstset{language=[GNU]C++,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
    225228
    226 \CC is largely backwards compatible with C, so it inherited C's enumerations.
    227 However, the following non-backwards compatible changes have been made.
     229\CC has the equivalent of Pascal typed @const@ declarations \see{\VRef{s:Pascal}}, with static and dynamic initialization.
     230\begin{c++}
     231const auto one = 0 + 1;                                 $\C{// static intialization}$
     232const auto NULL = nullptr;
     233const auto PI = 3.14159;
     234const auto Plus = '+';
     235const auto Fred = "Fred";
     236const auto Mon = 0, Tue = Mon + 1, Wed = Tue + 1, Thu = Wed + 1, Fri = Thu + 1,
     237                                Sat = Fri + 1, Sun = Sat + 1;
     238int sa[Sun];
     239const auto r = random();                                $\C{// dynamic intialization}$
     240int da[r];                                                              $\C{// VLA}$
     241\end{c++}
     242Statically initialized identifiers may appear in any constant-expression context, \eg @case@.
     243Dynamically intialized identifiers may appear as array dimensions in @g++@, which allows variable-sized arrays.
     244Interestingly, global \CC @const@ declarations are implicitly marked @static@ (@r@ rather than @R@).
     245\begin{c++}
     246$\$$ nm test.o
     2470000000000000018 @r@ Mon
     248\end{c++}
     249
     250\CC enumeration is largely backwards compatible with C, so it inherited C's enumerations.
     251However, the following non-backwards compatible changes are made.
    228252
    229253\begin{cquote}
     
    423447\begin{Go}
    424448const ( Mon = iota; Tue; Wed; // 0, 1, 2
    425          @Thu = 10@; Fri; Sat; Sun ) // 10, 10, 10, 10
     449        @Thu = 10@; Fri; Sat; Sun ) // 10, 10, 10, 10
    426450\end{Go}
    427451Auto-incrementing can be restarted with an expression containing \emph{one} \lstinline[language=Go]{iota}.
     
    429453const ( V1 = iota; V2; @V3 = 7;@ V4 = @iota@; V5 ) // 0 1 7 3 4
    430454const ( Mon = iota; Tue; Wed; // 0, 1, 2
    431          @Thu = 10;@ Fri = @iota - Wed + Thu - 1@; Sat; Sun ) // 10, 11, 12, 13
     455        @Thu = 10;@ Fri = @iota - Wed + Thu - 1@; Sat; Sun ) // 10, 11, 12, 13
    432456\end{Go}
    433457Note, \lstinline[language=Go]{iota} is advanced for an explicitly initialized enumerator, like the underscore @_@ identifier.
     
    12001224\lstnewenvironment{python}[1][]{\lstset{language=Python,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
    12011225
    1202 An @Enum@ is a set of symbolic names bound to unique values.
    1203 They are similar to global variables, but they offer a more useful @repr()@, grouping, type-safety, and a few other features.
    1204 
    1205 They are most useful when you have a variable that can take one of a limited selection of values. For example, the days of the week:
    1206 \begin{python}
    1207 >>> from enum import Enum
    1208 >>> class Weekday(Enum):
    1209 ...    MONDAY = 1
    1210 ...    TUESDAY = 2
    1211 ...    WEDNESDAY = 3
    1212 ...    THURSDAY = 4
    1213 ...    FRIDAY = 5
    1214 ...    SATURDAY = 6
    1215 ...    SUNDAY = 7
    1216 \end{python}
    1217 Or perhaps the RGB primary colors:
    1218 \begin{python}
    1219 >>> from enum import Enum
    1220 >>> class Color(Enum):
    1221 ...    RED = 1
    1222 ...    GREEN = 2
    1223 ...    BLUE = 3
    1224 \end{python}
    1225 As you can see, creating an @Enum@ is as simple as writing a class that inherits from @Enum@ itself.
    1226 
    1227 Note: Case of Enum Members
    1228 
    1229 Because Enums are used to represent constants, and to help avoid issues with name clashes between mixin-class methods/attributes and enum names, we strongly recommend using @UPPER_CASE@ names for members, and will be using that style in our examples.
     1226A Python enumeration is a set of symbolic names bound to \emph{unique} values.
     1227They are similar to global variables, but offer a more useful @repr()@, grouping, type-safety, and additional features.
     1228Enumerations inherits from the @Enum@ class, \eg:
     1229\begin{python}
     1230class Weekday(@Enum@): Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7
     1231class RGB(@Enum@): Red = 1; Green = 2; Blue = 3
     1232\end{python}
    12301233
    12311234Depending on the nature of the enum a member's value may or may not be important, but either way that value can be used to get the corresponding member:
    12321235\begin{python}
    1233 >>> Weekday(3)
    1234 <Weekday.WEDNESDAY: 3>
     1236print( repr( Weekday( 3 ) ) )
     1237<Weekday.Wed: 3>
    12351238\end{python}
    12361239As you can see, the @repr()@ of a member shows the enum name, the member name, and the value.
    12371240The @str()@ of a member shows only the enum name and member name:
    12381241\begin{python}
    1239 print(Weekday.THURSDAY)
    1240 Weekday.THURSDAY
     1242print( str( Weekday.Thu ), Weekday.Thu )
     1243Weekday.Thu Weekday.Thu
    12411244\end{python}
    12421245The type of an enumeration member is the enum it belongs to:
    12431246\begin{python}
    1244 >>> type(Weekday.MONDAY)
     1247print( type( Weekday.Thu ) )
    12451248<enum 'Weekday'>
    1246 isinstance(Weekday.FRIDAY, Weekday)
     1249print( isinstance(Weekday.Fri, Weekday) )
    12471250True
    12481251\end{python}
    12491252Enum members have an attribute that contains just their name:
    12501253\begin{python}
    1251 >>> print(Weekday.TUESDAY.name)
     1254print(Weekday.TUESDAY.name)
    12521255TUESDAY
    12531256\end{python}
    12541257Likewise, they have an attribute for their value:
    12551258\begin{python}
    1256 >>> Weekday.WEDNESDAY.value
     1259Weekday.WEDNESDAY.value
    125712603
    12581261\end{python}
     1262
    12591263Unlike many languages that treat enumerations solely as name/value pairs, Python @Enum@s can have behavior added.
    12601264For example, @datetime.date@ has two methods for returning the weekday: @weekday()@ and @isoweekday()@.
     
    12621266Rather than keep track of that ourselves we can add a method to the @Weekday@ enum to extract the day from the date instance and return the matching enum member:
    12631267\begin{python}
     1268class Weekday(Enum): Mon = 1; Tue = 2; Wed = 3; Thu = 10; Fri = 15; Sat = 16; Sun = 17
    12641269$@$classmethod
    12651270def from_date(cls, date):
    1266     return cls(date.isoweekday())
    1267 \end{python}
    1268 The complete Weekday enum now looks like this:
    1269 \begin{python}
    1270 >>> class Weekday(Enum):
    1271 ...    MONDAY = 1
    1272 ...    TUESDAY = 2
    1273 ...    WEDNESDAY = 3
    1274 ...    THURSDAY = 4
    1275 ...    FRIDAY = 5
    1276 ...    SATURDAY = 6
    1277 ...    SUNDAY = 7
    1278 ...    #
    1279 ...    $@$classmethod
    1280 ...    def from_date(cls, date):
    1281 ...        return cls(date.isoweekday())
     1271        return cls(date.isoweekday())
    12821272\end{python}
    12831273Now we can find out what today is! Observe:
     
    12911281This Weekday enum is great if our variable only needs one day, but what if we need several? Maybe we're writing a function to plot chores during a week, and don't want to use a @list@ -- we could use a different type of @Enum@:
    12921282\begin{python}
    1293 >>> from enum import Flag
    1294 >>> class Weekday(Flag):
    1295 ...    MONDAY = 1
    1296 ...    TUESDAY = 2
    1297 ...    WEDNESDAY = 4
    1298 ...    THURSDAY = 8
    1299 ...    FRIDAY = 16
    1300 ...    SATURDAY = 32
    1301 ...    SUNDAY = 64
     1283from enum import Flag
     1284class WeekdayF(@Flag@): Mon = @1@; Tue = @2@; Wed = @4@; Thu = @8@; Fri = @16@; Sat = @32@; Sun = @64@
    13021285\end{python}
    13031286We've changed two things: we're inherited from @Flag@, and the values are all powers of 2.
    13041287
    1305 Just like the original @Weekday@ enum above, we can have a single selection:
    1306 \begin{python}
    1307 >>> first_week_day = Weekday.MONDAY
    1308 >>> first_week_day
    1309 <Weekday.MONDAY: 1>
    1310 \end{python}
    1311 But @Flag@ also allows us to combine several members into a single variable:
    1312 \begin{python}
    1313 >>> weekend = Weekday.SATURDAY | Weekday.SUNDAY
    1314 >>> weekend
    1315 <Weekday.SATURDAY|SUNDAY: 96>
     1288@Flag@ allows combining several members into a single variable:
     1289\begin{python}
     1290print( repr(WeekdayF.Sat | WeekdayF.Sun) )
     1291<WeekdayF.Sun|Sat: 96>
    13161292\end{python}
    13171293You can even iterate over a @Flag@ variable:
    13181294\begin{python}
    1319 >>> for day in weekend:
    1320 ...    print(day)
     1295for day in weekend:
     1296        print(day)
    13211297Weekday.SATURDAY
    13221298Weekday.SUNDAY
     
    13821358\subsection{Duplicating enum members and values}
    13831359
    1384 Having two enum members with the same name is invalid:
    1385 \begin{python}
    1386 >>> class Shape(Enum):
    1387 ...    SQUARE = 2
    1388 ...    SQUARE = 3
    1389 ...
    1390 Traceback (most recent call last):
    1391 ...
    1392 TypeError: 'SQUARE' already defined as 2
    1393 \end{python}
    1394 However, an enum member can have other names associated with it.
     1360An enum member can have other names associated with it.
    13951361Given two entries @A@ and @B@ with the same value (and @A@ defined first), @B@ is an alias for the member @A@.
    13961362By-value lookup of the value of @A@ will return the member @A@.
     
    13981364By-name lookup of @B@ will also return the member @A@:
    13991365\begin{python}
    1400 >>> class Shape(Enum):
    1401 ...    SQUARE = 2
    1402 ...    DIAMOND = 1
    1403 ...    CIRCLE = 3
    1404 ...    ALIAS_FOR_SQUARE = 2
    1405 ...
     1366class Shape(Enum): SQUARE = 2; DIAMOND = 1; CIRCLE = 3; ALIAS_FOR_SQUARE = 2
    14061367>>> Shape.SQUARE
    14071368<Shape.SQUARE: 2>
     
    14191380When this behavior isn't desired, you can use the @unique()@ decorator:
    14201381\begin{python}
    1421 >>> from enum import Enum, unique
    1422 >>> $@$unique
    1423 ... class Mistake(Enum):
    1424 ...     ONE = 1
    1425 ...     TWO = 2
    1426 ...     THREE = 3
    1427 ...     FOUR = 3
    1428 ...
    1429 Traceback (most recent call last):
    1430 ...
     1382from enum import Enum, unique
     1383$@$unique
     1384class DupVal(Enum): ONE = 1; TWO = 2; THREE = 3; FOUR = 3
    14311385ValueError: duplicate values found in <enum 'Mistake'>: FOUR -> THREE
    14321386\end{python}
     
    14361390If the exact value is unimportant you can use @auto@:
    14371391\begin{python}
    1438 >>> from enum import Enum, auto
    1439 >>> class Color(Enum):
    1440 ...     RED = auto()
    1441 ...     BLUE = auto()
    1442 ...     GREEN = auto()
    1443 ...
    1444 >>> [member.value for member in Color]
    1445 [1, 2, 3]
    1446 \end{python}
    1447 The values are chosen by \_generate\_next\_value\_(), which can be overridden:
     1392from enum import Enum, auto
     1393class RGBa(Enum): RED = auto(); BLUE = auto(); GREEN = auto()
     1394\end{python}
     1395(Like Golang @iota@.)
     1396The values are chosen by @_generate_next_value_()@, which can be overridden:
    14481397\begin{python}
    14491398>>> class AutoName(Enum):
     
    15821531\begin{python}
    15831532class EnumName([mix-in, ...,] [data-type,] base-enum):
    1584     pass
     1533        pass
    15851534\end{python}
    15861535Also, subclassing an enumeration is allowed only if the enumeration does not define any members.
     
    16991648\begin{python}
    17001649Enum(
    1701     value='NewEnumName',
    1702     names=<...>,
    1703     *,
    1704     module='...',
    1705     qualname='...',
    1706     type=<mixed-in class>,
    1707     start=1,
    1708     )
     1650        value='NewEnumName',
     1651        names=<...>,
     1652        *,
     1653        module='...',
     1654        qualname='...',
     1655        type=<mixed-in class>,
     1656        start=1,
     1657        )
    17091658\end{python}
    17101659\begin{itemize}
     
    19351884\begin{python}
    19361885class IntEnum(int, Enum):
    1937     pass
     1886        pass
    19381887\end{python}
    19391888This demonstrates how similar derived enumerations can be defined;
     
    20702019\begin{python}
    20712020def __bool__(self):
    2072     return bool(self.value)
     2021        return bool(self.value)
    20732022\end{python}
    20742023Plain @Enum@ classes always evaluate as @True@.
     
    24142363
    24152364If @__new__()@ or @__init__()@ is defined, the value of the enum member will be passed to those methods:
    2416 \begin{python}
    2417 >>> class Planet(Enum):
    2418 ...     MERCURY = (3.303e+23, 2.4397e6)
    2419 ...     VENUS   = (4.869e+24, 6.0518e6)
    2420 ...     EARTH   = (5.976e+24, 6.37814e6)
    2421 ...     MARS    = (6.421e+23, 3.3972e6)
    2422 ...     JUPITER = (1.9e+27,   7.1492e7)
    2423 ...     SATURN  = (5.688e+26, 6.0268e7)
    2424 ...     URANUS  = (8.686e+25, 2.5559e7)
    2425 ...     NEPTUNE = (1.024e+26, 2.4746e7)
    2426 ...     def __init__(self, mass, radius):
    2427 ...         self.mass = mass       # in kilograms
    2428 ...         self.radius = radius   # in meters
    2429 ...     $\@$property
    2430 ...     def surface_gravity(self):
    2431 ...         # universal gravitational constant  (m3 kg-1 s-2)
    2432 ...         G = 6.67300E-11
    2433 ...         return G * self.mass / (self.radius * self.radius)
    2434 ...
    2435 >>> Planet.EARTH.value
    2436 (5.976e+24, 6378140.0)
    2437 >>> Planet.EARTH.surface_gravity
    2438 9.802652743337129
    2439 \end{python}
     2365\begin{figure}
     2366\begin{python}
     2367from enum import Enum
     2368class Planet(Enum):
     2369        MERCURY = ( 3.303E23, 2.4397E6 )
     2370        VENUS       = ( 4.869E24, 6.0518E6 )
     2371        EARTH       = (5.976E24, 6.37814E6)
     2372        MARS         = (6.421E23, 3.3972E6)
     2373        JUPITER    = (1.9E27,   7.1492E7)
     2374        SATURN     = (5.688E26, 6.0268E7)
     2375        URANUS    = (8.686E25, 2.5559E7)
     2376        NEPTUNE  = (1.024E26, 2.4746E7)
     2377        def __init__( self, mass, radius ):
     2378                self.mass = mass                # in kilograms
     2379                self.radius = radius    # in meters
     2380        def surface_gravity( self ):
     2381                # universal gravitational constant  (m3 kg-1 s-2)
     2382                G = 6.67300E-11
     2383                return G * self.mass / (self.radius * self.radius)
     2384for p in Planet:
     2385        print( f"{p.name}: {p.value}" )
     2386
     2387MERCURY: (3.303e+23, 2439700.0)
     2388VENUS: (4.869e+24, 6051800.0)
     2389EARTH: (5.976e+24, 6378140.0)
     2390MARS: (6.421e+23, 3397200.0)
     2391JUPITER: (1.9e+27, 71492000.0)
     2392SATURN: (5.688e+26, 60268000.0)
     2393URANUS: (8.686e+25, 25559000.0)
     2394NEPTUNE: (1.024e+26, 24746000.0)
     2395\end{python}
     2396\caption{Python Planet Example}
     2397\label{f:PythonPlanetExample}
     2398\end{figure}
     2399
    24402400
    24412401\subsection{TimePeriod}
     
    24642424\section{OCaml}
    24652425\lstnewenvironment{ocaml}[1][]{\lstset{language=OCaml,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
     2426
     2427% https://ocaml.org/docs/basic-data-types#enumerated-data-types
    24662428
    24672429OCaml provides a variant (union) type, where multiple heterogeneously-typed objects share the same storage.
     
    25532515With valediction,
    25542516  - Gregor Richards
     2517
     2518
     2519Date: Thu, 14 Mar 2024 21:45:52 -0400
     2520Subject: Re: OCaml "enums" do come with ordering
     2521To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>
     2522From: Gregor Richards <gregor.richards@uwaterloo.ca>
     2523
     2524On 3/14/24 21:30, Peter A. Buhr wrote:
     2525> I've marked 3 places with your name to shows places with enum ordering.
     2526>
     2527> type weekday = Mon | Tue | Wed | Thu | Fri | Sat | Sun
     2528> let day : weekday = Mon
     2529> let take_class( d : weekday ) =
     2530>       if d <= Fri then                                (* Gregor *)
     2531>               Printf.printf "weekday\n"
     2532>       else if d >= Sat then                   (* Gregor *)
     2533>               Printf.printf "weekend\n";
     2534>       match d with
     2535>               Mon | Wed -> Printf.printf "CS442\n" |
     2536>               Tue | Thu -> Printf.printf "CS343\n" |
     2537>               Fri -> Printf.printf "Tutorial\n" |
     2538>               _ -> Printf.printf "Take a break\n"
     2539>
     2540> let _ = take_class( Mon ); take_class( Sat );
     2541>
     2542> type colour = Red | Green of string | Blue of int * float
     2543> let c = Red
     2544> let _ = match c with Red -> Printf.printf "Red, "
     2545> let c = Green( "abc" )
     2546> let _ = match c with Green g -> Printf.printf "%s, " g
     2547> let c = Blue( 1, 1.5 )
     2548> let _ = match c with Blue( i, f ) -> Printf.printf "%d %g\n" i f
     2549>
     2550> let check_colour(c: colour): string =
     2551>       if c < Green( "xyz" ) then              (* Gregor *)
     2552>               Printf.printf "green\n";
     2553>       match c with
     2554>               Red -> "Red" |
     2555>               Green g -> g |
     2556>               Blue(i, f) -> string_of_int i ^ string_of_float f
     2557> let _ = check_colour( Red ); check_colour( Green( "xyz" ) );
     2558>
     2559> type stringList = Empty | Pair of string * stringList
     2560> let rec len_of_string_list(l: stringList): int =
     2561>       match l with
     2562>               Empty -> 0 |
     2563>               Pair(_ , r) -> 1 + len_of_string_list r
     2564>
     2565> let _ = for i = 1 to 10 do
     2566>       Printf.printf "%d, " i
     2567> done
     2568>
     2569> (* Local Variables: *)
     2570> (* tab-width: 4 *)
     2571> (* compile-command: "ocaml test.ml" *)
     2572> (* End: *)
     2573
     2574My functional-language familiarity is far more with Haskell than OCaml.  I
     2575mostly view OCaml through a lens of "it's Haskell but with cheating".  Haskell
     2576"enums" (ADTs) aren't ordered unless you specifically and manually put them in
     2577the Ord typeclass by defining the comparators.  Apparently, OCaml has some
     2578other rule, which I would guess is something like "sort by tag then by order of
     2579parameter". Having a default behavior for comparators is *bizarre*; my guess
     2580would be that it gained this behavior in its flirtation with object
     2581orientation, but that's just a guess (and irrelevant).
     2582
     2583This gives a total order, but not enumerability (which would still be
     2584effectively impossible or even meaningless since enums are just a special case
     2585of ADTs).
     2586
     2587With valediction,
     2588  - Gregor Richards
    25552589\end{comment}
    25562590
     
    25582592\section{Comparison}
    25592593
    2560 \begin{tabular}{r|ccccccccc}
    2561 feat. / lang. & Pascal  & Ada   & \Csharp       & OCaml & Java  & Modula-3      & Rust  & Swift & Python        \\
     2594\VRef[Table]{t:FeatureLanguageComparison} shows a comparison of enumeration features and programming languages.
     2595The features are high level and may not capture nuances within a particular language
     2596The @const@ feature is simple macros substitution and not a typed enumeration.
     2597
     2598\begin{table}
     2599\caption{Enumeration Feature / Language Comparison}
     2600\label{t:FeatureLanguageComparison}
     2601\small
     2602\setlength{\tabcolsep}{3pt}
     2603\newcommand{\CM}{\checkmark}
     2604\begin{tabular}{r|c|c|c|c|c|c|c|c|c|c|c|c|c}
     2605                                &Pascal & Ada   &\Csharp& OCaml & Java  &Modula-3&Golang& Rust  & Swift & Python& C             & \CC   & \CFA  \\
    25622606\hline
    2563 pure            &                       &               &                       &               &               &                       &               &               &                       \\
    2564 ordered         &                       &               &                       &               &               &                       &               &               &                       \\
    2565 setable         &                       &               &                       &               &               &                       &               &               &                       \\
    2566 auto-init       &                       &               &                       &               &               &                       &               &               &                       \\
    2567 scoped          &                       &               &                       &               &               &                       &               &               &                       \\
    2568 typed           &                       &               &                       &               &               &                       &               &               &                       \\
    2569 switch          &                       &               &                       &               &               &                       &               &               &                       \\
    2570 loop            &                       &               &                       &               &               &                       &               &               &                       \\
    2571 array           &                       &               &                       &               &               &                       &               &               &                       \\
     2607@const@                 & \CM   &               &               &               &               &               & \CM   &               &               &               &               & \CM   &               \\
     2608\hline
     2609\hline
     2610pure                    &               &               &               &               &               &               &               &               &               &               &               &               & \CM   \\
     2611\hline
     2612typed                   &               &               &               &               &               &               &               &               &               &               & @int@ & integral      & @T@   \\
     2613\hline
     2614safe                    &               &               &               &               &               &               &               &               &               &               &               & \CM   & \CM   \\
     2615\hline
     2616ordered                 &               &               &               &               &               &               &               &               &               &               & \CM   & \CM   & \CM   \\
     2617\hline
     2618dup. values             &               &               &               &               &               &               &               &               &               & alias & \CM   & \CM   & \CM   \\
     2619\hline
     2620setable                 &               &               &               &               &               &               &               &               &               &               & \CM   & \CM   & \CM   \\
     2621\hline
     2622auto-init               &               &               &               &               &               &               &               &               &               &               & \CM   & \CM   & \CM   \\
     2623\hline
     2624(un)scoped              &               &               &               &               &               &               &               &               &               &               & U             & U/S   & U/S   \\
     2625\hline
     2626overload                &               & \CM   &               &               &               &               &               &               &               &               &               & \CM   & \CM   \\
     2627\hline
     2628switch                  &               &               &               &               &               &               &               &               &               &               & \CM   & \CM   & \CM   \\
     2629\hline
     2630loop                    &               &               &               &               &               &               &               &               &               &               &               &               & \CM   \\
     2631\hline
     2632array                   &               &               &               &               &               &               &               &               &               &               & \CM   &               & \CM   \\
     2633\hline
     2634subtype                 &               &               &               &               &               &               &               &               &               &               &               &               & \CM   \\
     2635\hline
     2636inheritance             &               &               &               &               &               &               &               &               &               &               &               &               & \CM   \\
    25722637\end{tabular}
     2638\end{table}
Note: See TracChangeset for help on using the changeset viewer.