Ignore:
Timestamp:
Feb 5, 2024, 10:21:52 AM (5 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
23a0e576, b08ab18
Parents:
47bd204
Message:

add more material

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/enum.tex

    r47bd204 re11cdc0  
    117117\end{abstract}
    118118
    119 \section{Background}
     119\section{Introduction}
    120120
    121121Naming values is a common practice in mathematics and engineering, e.g., $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), MHz (1E6), etc.
    122 Naming 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), time (noon, New Years).
     122Naming 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).
    123123Many programming languages capture this important software-engineering capability through a mechanism called an \newterm{enumeration}.
    124124An 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.
     
    126126
    127127Specifically, an enumerated type restricts its values to a fixed set of named constants.
    128 Fundamentally, all types are restricted to a fixed set of values because of the underlying von Neumann architecture, and hence, to a corresponding set of constants, e.g., @3@, @3.5@, @3.5+2.1i@, @'c'@, @"abc"@, etc.
    129 However, the values for basic types are not named, other than the programming-language supplied constants.
    130 
    131 
    132 \section{C-Style Enum}
    133 
    134 The C-Style enumeration has the following syntax and semantics, and is representative of enumerations in many other programming languages (see Section~\ref{s:RelatedWork}).
    135 \begin{lstlisting}[label=lst:weekday]
    136 enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday };
    137                 $\(\uparrow\)$                                                                        $\(\uparrow\)$
    138     ${\rm \newterm{enumeration name}}$                                          ${\rm \newterm{enumerator names}}
    139 \end{lstlisting}
    140 Here, the enumeration type @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@.
    141 By convention, the successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@, independent of the associated enumerator constants.
    142 Because an enumerator is a constant, it cannot appear in a mutable context, e.g. @Mon = Sun@ is meaningless, and has no address, it is an rvalue\footnote{
    143 The term rvalue defines an expression that can only appear on the right-hand side of an assignment.}.
    144 Enumerators without explicitly designated constants are auto-initialized by the compiler: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@.
    145 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.
    146 Hence, there are 3 universal enumeration attributes: \newterm{position}, \newterm{label}, and \newterm{value}:
     128While all types are restricted to a fixed set of values because of the underlying von Neumann architecture, and hence, to a corresponding set of constants, e.g., @3@, @3.5@, @3.5+2.1i@, @'c'@, @"abc"@, etc., these values are not named, other than the programming-language supplied constants.
     129
     130Fundamentally, all enumeration systems have an \newterm{enumeration} type with its associated \newterm{enumerator} constants.
     131These components have three universal attributes, \newterm{position}, \newterm{label}, and \newterm{value}, as shown by this representative enumeration, where position and value can be different.
    147132\begin{cquote}
    148133\small\sf\setlength{\tabcolsep}{3pt}
    149134\begin{tabular}{rccccccccccc}
    150 @enum@ Weekday \{       & Monday,       & Tuesday,      & Wednesday,    & Thursday = 10,& Friday,       & Saturday,     & Sunday \}; \\
    151 \it\color{red}position          & 0                     & 1                     & 2                             & 3                             & 4                     & 5                     & 6                     \\
    152 \it\color{red}label                     & Monday        & Tuesday       & Wednesday             & Thursday              & Friday        & Saturday      & Sunday        \\
    153 \it\color{red}value                     & 0                     & 1                     & 2                             & {\color{red}10}& 11           & 12            & 13
     135\it\color{red}enumeration & \multicolumn{7}{c}{\it\color{red}enumerators}       \\
     136$\downarrow$\hspace*{25pt} & \multicolumn{7}{c}{$\downarrow$}                           \\
     137@enum@ Weekday \{                               & Monday,       & Tuesday,      & Wednesday,    & Thursday,& Friday,    & Saturday,     & Sunday \}; \\
     138\it\color{red}position                  & 0                     & 1                     & 2                             & 3                             & 4                     & 5                     & 6                     \\
     139\it\color{red}label                             & Monday        & Tuesday       & Wednesday             & Thursday              & Friday        & Saturday      & Sunday        \\
     140\it\color{red}value                             & 0                     & 1                     & 2                             & 3                             & 4                     & 5             & 6
    154141\end{tabular}
    155142\end{cquote}
    156 Finally, C enumerators are \newterm{unscoped}, i.e., enumerators declared inside of an @enum@ are visible in the enclosing scope of the @enum@ type.
     143Here, the \newterm{enumeration} @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@.
     144By convention, the successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@, independent of the associated enumerator constant values.
     145Because an enumerator is a constant, it cannot appear in a mutable context, e.g. @Mon = Sun@ is meaningless, and an enumerator has no address, it is an \newterm{rvalue}\footnote{
     146The term rvalue defines an expression that can only appear on the right-hand side of an assignment.}.
     147
     148
     149\section{C-Style Enum}
     150
     151The C-Style enumeration has the following syntax and semantics.
     152\begin{lstlisting}
     153enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday };
     154\end{lstlisting}
     155Enumerators 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@.
     156For 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@.
     157Initialization may occur in any order.
     158\begin{lstlisting}
     159enum Weekday { Thursday@ = 10@, Friday, Saturday, Sunday, Monday@ = 0@, Tuesday, Wednesday };
     160\end{lstlisting}
     161Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma.
     162\begin{lstlisting}
     163enum Weekday {
     164        Thursday = 10, Friday, Saturday, Sunday,
     165        Monday = 0, Tuesday, Wednesday@,@ // terminating comma
     166};
     167\end{lstlisting}
     168This feature allow enumerator lines to be interchanged without moving a comma.\footnote{
     169A terminating comma appears in other C syntax, e.g., the initializer list.}
     170Finally, C enumerators are \newterm{unscoped}, i.e., enumerators declared inside of an @enum@ are visible (projected) in the enclosing scope of the @enum@ type.
    157171
    158172In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerated values.
    159 In practice, since integral constants in C have type @int@ (unless qualified with a size suffix), C uses @int@ as the underlying type for enumeration variables.
    160 Furthermore, there is an implicit bidirectional conversion between an enumeration and integral types.
     173In 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.
     174Finally, there is an implicit bidirectional conversion between an enumeration and integral types.
    161175\begin{lstlisting}[label=lst:enum_scope]
    162176{
    163         enum Weekday { ... };                           $\C{// enumerators implicitly projected into local scope}$
     177        enum Weekday { /* as above */ };        $\C{// enumerators implicitly projected into local scope}$
    164178        Weekday weekday = Monday;                       $\C{// weekday == 0}$
    165179        weekday = Friday;                                       $\C{// weekday == 11}$
    166         int i = Sunday                                          $\C{// implicit conversion to int, i == 13}$
     180        int i = Sunday;                                         $\C{// implicit conversion to int, i == 13}$
    167181        weekday = 10000;                                        $\C{// UNDEFINED! implicit conversion to Weekday}$
    168182}
     
    171185The implicit conversion from @int@ to an enumeration type is an unnecessary source of error.
    172186
     187It is common for C programmers to ``believe'' there are 3 equivalent forms of constant enumeration.
     188\begin{lstlisting}[label=lst:enum_scope]
     189#define Monday 0
     190static const int Monday = 0;
     191enum { Monday };
     192\end{lstlisting}
     193For @#define@, the programmer has to play compiler and explicitly manage the enumeration values;
     194furthermore, these are independent constants outside of any language type mechanism.
     195The same explicit management is true for @const@ declarations, and the @const@ variable cannot appear in constant-expression locations, like @case@ labels, array dimensions,\footnote{
     196C 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.
     197Only the @enum@ form is managed by the compiler, is part of the language type-system, and works in all C constant-expression locations.
     198
     199
    173200\section{\CFA-Style Enum}
    174201
     
    176203\CFA also extends C-Style enumeration by adding a number of new features that bring enumerations inline with other modern programming languages.
    177204
     205
     206\subsection{Enumerator Name Resolution}
     207\label{s:EnumeratorNameResolution}
     208
     209In C, unscoping of enumerators presents a \newterm{naming problem} when multiple enumeration types appear in the same scope with duplicate enumerator names.
     210There is no mechanism in C to resolve these naming conflicts other than renaming of one of the duplicates, which may not be possible.
     211
     212The \CFA type-system allows extensive overloading, including enumerators.
     213Furthermore, \CFA uses the left-hand of assignment in type resolution to pinpoint the best overloaded name.
     214Finally, qualification is provided to disambiguate any ambiguous situations.
     215\begin{lstlisting}
     216enum C1 { First, Second, Third, Fourth };
     217enum C2 { @Fourth@, @Third@, @Second@, @First@ };
     218C1 p() { return Third; }                                $\C{// correctly resolved duplicate names}$
     219C2 p() { return Fourth; }
     220void foo() {
     221        C1 e1 = First;   C2 e2 = First;
     222        e1 = Second;   e2 = Second;
     223        e1 = p();   e2 = p();
     224        e1 = @C1.@First + @C1.@First;           $\C{// ambiguous without qualification (and dangerous)}$
     225}
     226\end{lstlisting}
     227\CFA overloading allows programmers to use the most meaningful names with little fear of unresolvable clashes from included files, which can always be corrected.
     228
     229
     230\subsection{Enumerator Scoping}
     231
     232An enumeration can be scoped, so the enumerator constants are not projected into the enclosing scope, using @'!'@.
     233\begin{lstlisting}
     234enum Weekday @!@ { /* as above */ };
     235enum( char * ) Names @!@ { /* as above */ };
     236\end{lstlisting}
     237Now the enumerators must be qualified with the associated enumeration.
     238\begin{lstlisting}
     239Weekday weekday = @Weekday@.Monday;
     240Names names = @Names.@Fred;
     241names = @Names.@Jane;
     242\end{lstlisting}
     243It is possible to toggle back to unscoping using the \CFA @with@ clause/statement.
     244\begin{lstlisting}
     245Weekday weekday;
     246with ( @Weekday@, @Names@ ) {                   $\C{// type names}$
     247         Names names = @Fred@;
     248         names = @Jane@;
     249         weekday = Saturday;
     250}
     251\end{lstlisting}
     252As 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 ambiguities.
     253
     254
    178255\subsection{Enumerator Typing}
    179256
    180 \CFA extends the enumeration by parameterizing the enumeration with a type for the enumerators, allowing enumerators to be assigned any values from the declared type.
    181 Figure~\ref{f:EumeratorTyping} shows a series of examples illustrating that all \CFA types can be use with an enumeration and each type's constants used to set the enumerators.
    182 
    183 Typed enumerates deals with \emph{harmonizing} problem between an enumeration and its companion data.
    184 The following example is from the \CFA compiler, written in \CC.
    185 \begin{lstlisting}
    186 enum integral_types { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES };
    187 char * integral_names[NO_OF_ITYPES] = {
    188         "char", "signed char", "unsigned char",
    189         "signed short int", "unsigned short int",
    190         "signed int", "unsigned int",
    191         ...
    192 };
    193 \end{lstlisting}
    194 The \emph{harmonizing} problem occurs because the enumeration declaration is in one header file and the names are declared in another translation unit.
    195 It is up to the programmer to ensure changes made in one location are harmonized with the other location (by identifying this requirement within a comment).
    196 The typed enumeration largely solves this problem by combining and managing the two data types.
    197 \begin{lstlisting}
    198 enum( char * ) integral_types {
    199         chr = "char", schar = "signed char", uschar = "unsigned char",
    200         sshort = "signed short int", ushort = "unsigned short int",
    201         sint = "signed int", usint = "unsigned int",
    202         ...
    203 };
    204 \end{lstlisting}
     257\CFA extends the enumeration declaration by parameterizing with a type (like a generic type), allowing enumerators to be assigned any values from the declared type.
     258Figure~\ref{f:EumeratorTyping} shows a series of examples illustrating that all \CFA types can be use with an enumeration and each type's constants used to set the enumerator constants.
     259Note, the synonyms @Liz@ and @Beth@ in the last declaration.
    205260
    206261% \begin{lstlisting}[label=lst:color]
     
    223278        enum( @_Complex@ ) Plane { X = 1.5+3.4i, Y = 7+3i, Z = 0+0.5i };
    224279// pointer
    225         enum( @char *@ ) Names { Fred = "Fred", Mary = "Mary", Jane = "Jane" };
     280        enum( @char *@ ) Names { Fred = "FRED", Mary = "MARY", Jane = "JANE" };
    226281        int i, j, k;
    227282        enum( @int *@ ) ptr { I = &i,  J = &j,  K = &k };
    228283        enum( @int &@ ) ref { I = i,   J = j,   K = k };
    229284// tuple
    230         enum( @[int, int]@ ) { T = [ 1, 2 ] };
     285        enum( @[int, int]@ ) { T = [ 1, 2 ] }; $\C{// new \CFA type}$
    231286// function
    232287        void f() {...}   void g() {...}
     
    234289// aggregate
    235290        struct Person { char * name; int age, height; };
    236         enum( @Person@ ) friends { Liz = { "Elizabeth", 22, 170 }, Beth = Liz, Jon = { "Jonathan", 35, 190 } };
     291@***@enum( @Person@ ) friends { @Liz@ = { "ELIZABETH", 22, 170 }, @Beth@ = Liz, Jon = { "JONATHAN", 35, 190 } };
    237292\end{lstlisting}
    238293\caption{Enumerator Typing}
     
    240295\end{figure}
    241296
     297Typed enumerations deals with the \emph{harmonizing} problem between an enumeration and any companion data.
     298The following example is from the \CFA compiler, written in \CC.
     299\begin{lstlisting}
     300enum integral_types { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES };
     301char * integral_names[NO_OF_ITYPES] = {
     302        "char", "signed char", "unsigned char",
     303        "signed short int", "unsigned short int",
     304        "signed int", "unsigned int",
     305        ...
     306};
     307\end{lstlisting}
     308The \emph{harmonizing} problem occurs because the enumeration declaration is in one header file and the names are declared in another translation unit.
     309It is up to the programmer to ensure changes made in one location are harmonized with the other location (by identifying this requirement within a comment).
     310The typed enumeration largely solves this problem by combining and managing the two data types.
     311\begin{lstlisting}
     312enum( char * ) integral_types {
     313        chr = "char", schar = "signed char", uschar = "unsigned char",
     314        sshort = "signed short int", ushort = "unsigned short int",
     315        sint = "signed int", usint = "unsigned int",
     316        ...
     317};
     318\end{lstlisting}
     319
    242320\subsection{Pure Enumerators}
    243321
     
    247325\begin{lstlisting}
    248326enum() Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND };
    249 Mode iomode = O_RDONLY;
     327@***@Mode iomode = O_RDONLY;
    250328int i = iomode;                                                 $\C{\color{red}// disallowed}$
    251 sout | O_TRUNC;                                                 $\C{\color{red}// disallowed}$
    252329\end{lstlisting}
    253330
    254331\subsection{Enumerator Subset}
    255332
    256 If follows from enumerator typing that the type of the enumerators can be another enumerator.
     333If follows from enumerator typing that the enumerator type can be another enumerator.
    257334\begin{lstlisting}
    258335enum( char ) Letter { A = 'A',  B = 'B', C = 'C', ..., Z = 'Z' };
    259 enum( Letter ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // alphabet intersection
    260 Letter letter = A;
    261 Greak greek = Alph;
    262 letter = Alph;                                                  $\C{// allowed}$
    263 greek = A;                                                              $\C{\color{red}// disallowed}$
     336enum( @Letter@ ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // alphabet intersection
    264337\end{lstlisting}
    265338Enumeration @Greek@ may have more or less enumerators than @Letter@, but the enumerator values must be from @Letter@.
    266339Therefore, @Greek@ enumerators are a subset of type @Letter@ and are type compatible with enumeration @Letter@, but @Letter@ enumerators are not type compatible with enumeration @Greek@.
     340\begin{lstlisting}
     341Letter letter = A;
     342@***@Greak greek = Beta;
     343letter = Beta;                                                  $\C{// allowed, letter == B}$
     344greek = A;                                                              $\C{\color{red}// disallowed}$
     345\end{lstlisting}
     346
    267347
    268348\subsection{Enumeration Inheritance}
     
    270350\CFA Plan-9 inheritance may be used with enumerations.
    271351\begin{lstlisting}
    272 enum( char * ) Name2 { @inline Name@, Jack = "Jack", Jill = "Jill" };
    273 enum /* inferred */ Name3 { @inline Name2@, Sue = "Sue", Tom = "Tom" };
    274 \end{lstlisting}
    275 Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Name@ by containment, and a @Name@ enumeration is a subtype of enumeration @Name2@.
     352enum( char * ) Names { /* as above */ };
     353enum( char * ) Names2 { @inline Names@, Jack = "JACK", Jill = "JILL" };
     354@***@enum /* inferred */ Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" };
     355\end{lstlisting}
     356Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Names@ by containment, and a @Names@ enumeration is a subtype of enumeration @Name2@.
    276357Note, enumerators must be unique in inheritance but enumerator values may be repeated.
    277358
    278359The enumeration type for the inheriting type must be the same as the inherited type;
    279360hence the enumeration type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for @Name3@.
    280 When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important.
    281 
    282 Specifically, the inheritance relationship for Names is:
    283 \begin{lstlisting}
    284 Name $\(\subset\)$ Name2 $\(\subset\)$ Name3 $\(\subset\)$ const char *         // enum type of Name
     361% When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important.
     362Specifically, the inheritance relationship for @Names@ is:
     363\begin{lstlisting}
     364Names $\(\subset\)$ Names2 $\(\subset\)$ Names3 $\(\subset\)$ const char * $\C{// enum type of Names}$
    285365\end{lstlisting}
    286366For the given function prototypes, the following calls are valid.
     
    288368\begin{tabular}{ll}
    289369\begin{lstlisting}
    290 void f( Name );
    291 void g( Name2 );
    292 void h( Name3 );
     370void f( Names );
     371void g( Names2 );
     372void h( Names3 );
    293373void j( const char * );
    294374\end{lstlisting}
     
    298378g( Fred );   g( Jill );
    299379h( Fred );   h( Jill );   h( Sue );
    300 j( Fred );   j( Jill );   j( Sue );   j( "Will" );
     380j( Fred );   j( Jill );   j( Sue );   j( "WILL" );
    301381\end{lstlisting}
    302382\end{tabular}
     
    304384Note, the validity of calls is the same for call-by-reference as for call-by-value, and const restrictions are the same as for other types.
    305385
    306 \subsection{Enumerator Scoping}
    307 
    308 A \CFA-enum can be scoped, meaning the enumerator constants are not projected into the enclosing scope.
    309 \begin{lstlisting}
    310 enum Weekday @!@ { /* as above */ };
    311 enum Colour( char * ) @!@ { /* as above */ };
    312 \end{lstlisting}
    313 where the @'!'@ implies the enumerators are \emph{not} projected.
    314 The enumerators of a scoped enumeration are accessed using qualifications, like the fields of an aggregate.
    315 % The syntax of $qualified\_expression$ for \CFA-enum is the following:
    316 % $$<qualified\_expression> := <enum\_type>.<enumerator>$$
    317 \begin{lstlisting}
    318 Weekday weekday = @Weekday.Monday@;             $\C{// qualification}$
    319 Colour colour = @Colour.@Red;
    320 colour = @Colour.@Blue;
    321 \end{lstlisting}
    322386
    323387\subsection{Enumeration Pseudo-functions}
     
    326390Often a call to a pseudo-function is substituted with information extracted from the symbol table at compilation time, like storage size or alignment associated with the underlying architecture..
    327391
     392
    328393\subsubsection{Enumerator Attributes}
    329394The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@.
    330395\begin{lstlisting}
    331 int green_pos = @position@( Colour.Green );     $\C{// 1}$
    332 char * green_value = @value@( Colour.Green ); $\C{// "G"}$
    333 char * green_label = @label@( Colour.Green ); $\C{// "Green"}$
    334 \end{lstlisting}
    335 
    336 Enumeration Greek may have more or less enumerators than Letter, but the enumerator values must be from Letter.
    337 Therefore, Greek enumerators are a subset of type Letter and are type compatible with enumeration Letter, but Letter enumerators are not type compatible with enumeration Greek.
     396@***@int jane_pos = position( Names.Jane );   $\C{// 2}$
     397@***@char * jane_value = value( Names.Jane ); $\C{// "JANE"}$
     398@***@char * jane_label = label( Names.Jane ); $\C{// "Jane"}$
     399\end{lstlisting}
    338400
    339401% An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name.
     
    341403% Similarly, the @value()@ function returns the value used to initialize the \CFA-enum.
    342404
    343 \subsubsection{\lstinline{enumerate()}}
    344 
    345 \begin{lstlisting}[label=lst:c_switch]
    346 enum(int) C_ENUM { First, Second, Third = First, Fourth };
    347 int v( C_ENUM e ) {
    348         switch( e ) {
    349                 case First: return 0; break;
    350                 case Second: return 1; break;
    351                 // case Third: return 2; break;
    352                 // case Fourth: return 3; break;
    353         };
    354 };
    355 \end{lstlisting}
    356 In the @C_ENUM@ example, @Third@ is an alias of @First@ and @Fourth@ is an alias of @Second@.
    357 Programmers cannot make case branches for @Third@ and @Fourth@ because the switch statement matches cases by the enumerator's value.
    358 Case @First@ and @Third@, or @Second@ and @Fourth@, has duplicate case values.
    359 
    360 @enumerate()@ is a pseudo-function that makes the switch statement match by an enumerator instead.
    361 \begin{lstlisting}[label=lst:c_switch_enumerate]
    362 enum(double) C_ENUM { First, Second, Third = First, Fourth };
    363 C_ENUM variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth;
    364 int v(C_ENUM e) {
    365         switch( enumeratate( e ) ) {
    366                 case First: return e; break;
    367                 case Second: return value( e ); break;
    368                 case Third: return label( e ); break;
    369                 case Fourth: return position( e ); break;
    370         };
    371 };
     405
     406\subsubsection{\lstinline{switch/choose} Statement}
     407
     408An intuitive use of enumerations is with the \CFA @switch@/@choose@ statement, where @choose@ performs an implict @break@ rather than a fall-through at the end of a @case@ clause.
     409\begin{lstlisting}
     410enum Count { First, Second, Third, Fourth };
     411Count e;
     412\end{lstlisting}
     413\begin{cquote}
     414\begin{tabular}{ll}
     415\begin{lstlisting}
     416choose( e ) {
     417        case @First@: ...;
     418        case @Second@: ...;
     419        case @Third@: ...;
     420        case @Fourth@: ...;
     421}
     422\end{lstlisting}
     423&
     424\begin{lstlisting}
     425choose( @value@( e ) ) {
     426        case @value@( First ): ...;
     427        case @value@( Second ): ...;
     428        case @value@( Third ): ...;
     429        case @value@( Fourth ): ...;
     430}
     431\end{lstlisting}
     432\end{tabular}
     433\end{cquote}
     434Here, the intuitive implementation on the right uses the value of the enumeration and enumerators.
     435However, this implementation is fragile, e.g., if the enumeration is changed to:
     436\begin{lstlisting}
     437enum Count { First, Second, Third @= First@, Fourth };
     438\end{lstlisting}
     439which make @Third == First@ and @Fourth == Second@, causing duplicase @case@ clauses.
     440To better match with programmer intuition, \CFA uses a more robust implementation form when the type of a @switch@ expression is an enumeration.
     441\begin{lstlisting}
     442choose( @position@( e ) ) {
     443        case @position@( First ): ...;
     444        case @position@( Second ): ...;
     445        case @position@( Third ): ...;
     446        case @position@( Fourth ): ...;
     447}
     448\end{lstlisting}
     449
     450\begin{lstlisting}
     451Count variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth;
    372452p(variable_a); // 0
    373453p(variable_b); // 1
     
    10151095If the @aggregation_name@ is identified as a \CFA enumeration, the compiler checks if @field@ presents in the declared \CFA enumeration.
    10161096
    1017 \subsection{\lstinline{with} Clause/Statement}
    1018 
    1019 Instead of qualifying an enumeration expression every time, the @with@ can be used to expose enumerators to the current scope, making them directly accessible.
    1020 \begin{lstlisting}[label=lst:declaration]
    1021 enum Color( char * ) { Red="R", Green="G", Blue="B" };
    1022 enum Animal( int ) { Cat=10, Dog=20 };
    1023 with ( Color, Animal ) {
    1024         char * red_string = Red; // value( Color.Red )
    1025         int cat = Cat; // value( Animal.Cat )
    1026 }
    1027 \end{lstlisting}
    1028 The \lstinline{with} might introduce ambiguity to a scope. Consider the example:
    1029 \begin{lstlisting}[label=lst:declaration]
    1030 enum Color( char * ) { Red="R", Green="G", Blue="B" };
    1031 enum RGB( int ) { Red=0, Green=1, Blue=2 };
    1032 with ( Color, RGB ) {
    1033         // int red = Red;
    1034 }
    1035 \end{lstlisting}
    1036 \CFA will not try to resolve the expression with ambiguity. It would report an error. In this case, it is necessary to qualify @Red@ even inside of the \lstinline{with} clause.
    1037 
    10381097\subsection{Instance Declaration}
    10391098
Note: See TracChangeset for help on using the changeset viewer.