Changeset d63746f


Ignore:
Timestamp:
Feb 7, 2024, 5:11:49 PM (10 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
a22d148
Parents:
b08ab18
Message:

more updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/enum.tex

    rb08ab18 rd63746f  
    126126
    127127Specifically, an enumerated type restricts its values to a fixed set of named constants.
    128 While 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 
    130 Fundamentally, all enumeration systems have an \newterm{enumeration} type with its associated \newterm{enumerator} constants.
    131 These 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.
     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 constant names.
     129
     130Fundamentally, all enumeration systems have an \newterm{enumeration} type with an associated set of \newterm{enumerator} names.
     131An 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.
    132132\begin{cquote}
    133133\small\sf\setlength{\tabcolsep}{3pt}
     
    168168This feature allow enumerator lines to be interchanged without moving a comma.\footnote{
    169169A terminating comma appears in other C syntax, e.g., the initializer list.}
    170 Finally, C enumerators are \newterm{unscoped}, i.e., enumerators declared inside of an @enum@ are visible (projected) in the enclosing scope of the @enum@ type.
     170Finally, C enumerators are \newterm{unscoped}, i.e., enumerators declared inside of an @enum@ are visible (projected) into the enclosing scope of the @enum@ type.
    171171
    172172In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerated values.
     
    208208
    209209In C, unscoping of enumerators presents a \newterm{naming problem} when multiple enumeration types appear in the same scope with duplicate enumerator names.
    210 There is no mechanism in C to resolve these naming conflicts other than renaming of one of the duplicates, which may not be possible.
     210There is no mechanism in C to resolve these naming conflicts other than renaming of one of the duplicates, which may be impossible.
    211211
    212212The \CFA type-system allows extensive overloading, including enumerators.
     
    221221        C1 e1 = First;   C2 e2 = First;
    222222        e1 = Second;   e2 = Second;
    223         e1 = p();   e2 = p();
    224         e1 = @C1.@First + @C1.@First;           $\C{// ambiguous without qualification (and dangerous)}$
     223        e1 = p();   e2 = p();                           $\C{// correctly resolved function call}$
     224        int i = @C1.@First + @C2.@First;        $\C{// ambiguous without qualification}$
    225225}
    226226\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.
     227\CFA overloading allows programmers to use the most meaningful names without fear of unresolvable clashes from included files, which are correctable with qualification.
    228228
    229229
     
    235235enum( char * ) Names @!@ { /* as above */ };
    236236\end{lstlisting}
    237 Now the enumerators must be qualified with the associated enumeration.
     237Now the enumerators \emph{must} be qualified with the associated enumeration.
    238238\begin{lstlisting}
    239239Weekday weekday = @Weekday@.Monday;
     
    241241names = @Names.@Jane;
    242242\end{lstlisting}
    243 It is possible to toggle back to unscoping using the \CFA @with@ clause/statement.
     243It 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}).
    244244\begin{lstlisting}
    245245Weekday weekday;
     
    250250}
    251251\end{lstlisting}
    252 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 ambiguities.
    253 
     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 name resolution.
    254253
    255254\subsection{Enumerator Typing}
     
    258257Figure~\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.
    259258Note, the synonyms @Liz@ and @Beth@ in the last declaration.
     259
     260Because enumerators are constants, the enumeration type is implicitly @const@, so all the enumerator types in Figure~\ref{f:EumeratorTyping} are rewritten with @const@.
     261A typed enumeration has an implicit (safe) conversion to its base type.
     262\begin{lstlisting}
     263char currency = Dollar;
     264string fred = Fred;                                             $\C{// implicit conversion from char * to \CFA string type}$
     265Person student = Beth;
     266\end{lstlisting}
    260267
    261268% \begin{lstlisting}[label=lst:color]
     
    317324};
    318325\end{lstlisting}
     326Note, the enumeration type can be a structure (see @Person@ in Figure~\ref{f:EumeratorTyping}), so it is possible to have the equivalent of multiple arrays of companion data using an array of structures.
     327
    319328
    320329\subsection{Pure Enumerators}
    321330
    322 An empty type, @enum()@, implies the enumerators are pure symbols without values;
     331An empty enumerator type, @enum()@, implies the enumerators are pure symbols without values but set properties;
    323332hence, there is no default conversion to @int@.
    324333
     
    326335enum() Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND };
    327336@***@Mode iomode = O_RDONLY;
     337bool b = iomode == O_RDONLY || iomode < O_APPEND;
    328338int i = iomode;                                                 $\C{\color{red}// disallowed}$
    329339\end{lstlisting}
     
    333343If follows from enumerator typing that the enumerator type can be another enumerator.
    334344\begin{lstlisting}
     345enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$'  };
     346enum( @Currency@ ) Europe { Euro = Currency.Euro, Pound = Currency.Pound }; // intersection
    335347enum( char ) Letter { A = 'A',  B = 'B', C = 'C', ..., Z = 'Z' };
    336 enum( @Letter@ ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // alphabet intersection
    337 \end{lstlisting}
    338 Enumeration @Greek@ may have more or less enumerators than @Letter@, but the enumerator values must be from @Letter@.
    339 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@.
     348enum( @Letter@ ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // intersection
     349\end{lstlisting}
     350Subset enumerations may have more or less enumerators than their typed enumeration, but the enumerator values must be from the typed enumeration.
     351For example, @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@.
    340352\begin{lstlisting}
    341353Letter letter = A;
     
    348360\subsection{Enumeration Inheritance}
    349361
    350 \CFA Plan-9 inheritance may be used with enumerations.
     362\CFA Plan-9 inheritance may be used with enumerations, where Plan-9 inheritance is containment inheritance with implicit unscoping (like a nested unnamed @struct@/@union@ in C).
    351363\begin{lstlisting}
    352364enum( char * ) Names { /* as above */ };
     
    382394\end{tabular}
    383395\end{cquote}
    384 Note, 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.
     396Note, 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.
    385397
    386398
    387399\subsection{Enumeration Pseudo-functions}
    388400
    389 Pseudo-functions are function-like operators that do not result in any run-time computations, i.e., like @sizeof@.
     401Pseudo-functions are function-like operators that do not result in any run-time computations, i.e., like @sizeof@, @offsetof@, @typeof@.
    390402Often 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..
    391403
    392 
    393 \subsubsection{Enumerator Attributes}
    394404The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@.
    395405\begin{lstlisting}
    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}
    400 
    401 % An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name.
    402 % The label can be retrieved by calling the function @label( <enum_instance> )@.
    403 % Similarly, the @value()@ function returns the value used to initialize the \CFA-enum.
    404 
    405 
    406 \subsubsection{\lstinline{switch/choose} Statement}
    407 
    408 An 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.
     406@***@int jane_pos = @position@( Names.Jane );   $\C{// 2}$
     407@***@char * jane_value = @value@( Names.Jane ); $\C{// "JANE"}$
     408@***@char * jane_label = @label@( Names.Jane ); $\C{// "Jane"}$
     409sout | @label@( Names.Jane ) | @value@( Names.Jane );
     410\end{lstlisting}
     411Note the ability to print both enumerator label and value.
     412
     413
     414\subsection{Enumerator Position or Value}
     415
     416Enumerators can be used in multiple contexts.
     417In most programming languages, an enumerator is implicitly converted to its value (like a typed macro substitution).
     418However, enumerator synonyms and typed enumerations make this implicit conversion to value incorrect in some contexts.
     419In these contexts, a programmer's initition assumes an implicit conversion to postion.
     420
     421For example, an 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.
     422\begin{cquote}
    409423\begin{lstlisting}
    410424enum Count { First, Second, Third, Fourth };
    411425Count e;
    412426\end{lstlisting}
    413 \begin{cquote}
    414427\begin{tabular}{ll}
    415428\begin{lstlisting}
     429
    416430choose( e ) {
    417431        case @First@: ...;
     
    423437&
    424438\begin{lstlisting}
     439// rewrite
    425440choose( @value@( e ) ) {
    426441        case @value@( First ): ...;
     
    432447\end{tabular}
    433448\end{cquote}
    434 Here, the intuitive implementation on the right uses the value of the enumeration and enumerators.
     449Here, the intuitive code on the left is implicitly transformed into the statndard implementation on the right, using the value of the enumeration variable and enumerators.
    435450However, this implementation is fragile, e.g., if the enumeration is changed to:
    436451\begin{lstlisting}
    437452enum Count { First, Second, Third @= First@, Fourth };
    438453\end{lstlisting}
    439 which make @Third == First@ and @Fourth == Second@, causing duplicase @case@ clauses.
    440 To better match with programmer intuition, \CFA uses a more robust implementation form when the type of a @switch@ expression is an enumeration.
     454which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicase @case@ clauses.
     455To better match with programmer intuition, \CFA toggles between value and position semantics depneding on the language context.
     456For conditional clauses and switch statments, \CFA uses the robust position implementation.
    441457\begin{lstlisting}
    442458choose( @position@( e ) ) {
     
    12771293
    12781294\subsection{\CC}
    1279 
    1280 \CC is backwards compatible with C, so it inherited C's enumerations, except there is no implicit conversion from an integral value to an enumeration;
    1281 hence, the values in a \CC enumeration can only be its enumerators (without a cast).
    1282 There is no mechanism to iterate through an enumeration.
    1283 
    1284 \CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), so the enumerators are local to the enumeration and must be accessed using type qualification, e.g., @Weekday::Monday@.
     1295\label{s:C++RelatedWork}
     1296
     1297\CC is backwards compatible with C, so it inherited C's enumerations.
     1298However, the following non-backwards compatible changes have been made.
     1299\begin{quote}
     13007.2 Change: \CC objects of enumeration type can only be assigned values of the same enumeration type.
     1301In C, objects of enumeration type can be assigned values of any integral type. \\
     1302Example:
     1303\begin{lstlisting}
     1304enum color { red, blue, green };
     1305color c = 1;                                                    $\C{// valid C, invalid C++}$
     1306\end{lstlisting}
     1307\textbf{Rationale}: The type-safe nature of C++. \\
     1308\textbf{Effect on original feature}: Deletion of semantically well-defined feature. \\
     1309\textbf{Difficulty of converting}: Syntactic transformation. (The type error produced by the assignment can be automatically corrected by applying an explicit cast.) \\
     1310\textbf{How widely used}: Common.
     1311\end{quote}
     1312\begin{quote}
     13137.2 Change: In \CC, the type of an enumerator is its enumeration.
     1314In C, the type of an enumerator is @int@. \\
     1315Example:
     1316\begin{lstlisting}
     1317enum e { A };
     1318sizeof(A) == sizeof(int)                                $\C{// in C}$
     1319sizeof(A) == sizeof(e)                                  $\C{// in C++}$
     1320/* and sizeof(int) is not necessary equal to sizeof(e) */
     1321\end{lstlisting}
     1322\textbf{Rationale}: In C++, an enumeration is a distinct type. \\
     1323\textbf{Effect on original feature}: Change to semantics of well-defined feature. \\
     1324\textbf{Difficulty of converting}: Semantic transformation. \\
     1325\textbf{How widely used}: Seldom. The only time this affects existing C code is when the size of an enumerator is taken.
     1326Taking the size of an enumerator is not a common C coding practice.
     1327\end{quote}
     1328Hence, the values in a \CC enumeration can only be its enumerators (without a cast).
     1329While the storage size of an enumerator is up to the compiler, there is still an implicit cast to @int@.
     1330\begin{lstlisting}
     1331enum E { A, B, C };
     1332E e = A;
     1333int i = A;   i = e;                                             $\C{// implicit casts to int}$
     1334\end{lstlisting}
     1335\CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), so the enumerators are local to the enumeration and must be accessed using type qualification.
     1336\begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}]
     1337enum class E { A, B, C };
     1338E e = @E::@A;                                                   $\C{// qualified enumerator}$
     1339e = B;                                                                  $\C{// B not in scope}$
     1340\end{lstlisting}
    12851341\CC{20} supports unscoped access with a \lstinline[language=c++]{using enum} declaration.
    1286 
    1287 For both unscoped and scoped enumerations, the 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.
    1288 In \CC{11}, the underlying integral type can be explicitly specified:
    12891342\begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}]
    1290 enum class RGB : @long@ { Red, Green, Blue };
    1291 enum class rgb : @char@ { Red = 'r', Green = 'g', Blue = 'b' };
    1292 enum class srgb : @signed char@ { Red = -1, Green = 0, Blue = 1 };
    1293 RGB colour1 = @RGB::@Red;
    1294 rgb colour2 = @rgb::@Red;
    1295 srgb colour3 = @srgb::@Red;
    1296 \end{lstlisting}
     1343enum class E { A, B, C };
     1344@using enum E;@
     1345E e = A;                                                                $\C{// direct access}$
     1346e = B;                                                                  $\C{// direct access}$
     1347\end{lstlisting}
     1348\CC{11} added the ability to explicitly declare the underlying integral type for \lstinline[language=c++]{enum class}.
     1349\begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}]
     1350enum class RGB @: long@ { Red, Green, Blue };
     1351enum class rgb @: char@ { Red = 'r', Green = 'g', Blue = 'b' };
     1352enum class srgb @: signed char@ { Red = -1, Green = 0, Blue = 1 };
     1353\end{lstlisting}
     1354There is no implicit conversion from the \lstinline[language=c++]{enum class} type and to its type.
     1355\begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}]
     1356rgb crgb = rgb::Red;
     1357char ch = rgb::Red;   ch = crgb;                $\C{// disallowed}$
     1358\end{lstlisting}
     1359Finally, there is no mechanism to iterate through an enumeration nor use the enumeration type to declare an array dimension.
     1360
    12971361
    12981362\subsection{Go}
Note: See TracChangeset for help on using the changeset viewer.