- Timestamp:
- May 12, 2024, 8:42:31 PM (7 months ago)
- Branches:
- master
- Children:
- bf4fe05
- Parents:
- 07e9df1
- Location:
- doc/theses/jiada_liang_MMath
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/CFAenum.tex
r07e9df1 rec20ab9 11 11 12 12 C already provides @const@-style aliasing using the unnamed enumerator \see{\VRef{s:TypeName}}, even if the name @enum@ is misleading (@const@ would be better). 13 Given the existence of this form, it is straightforward to extend it with types other than integers.13 Given the existence of this form, it is straightforward to extend it with types other than @int@. 14 14 \begin{cfa} 15 15 enum E { Size = 20u, PI = 3.14159L, Jack = L"John" }; … … 21 21 22 22 23 \section{Enumerator Unscoping}24 \label{s:Enumerator Unscoping}25 26 In C, unscoped enumerators present sa \newterm{naming problem} when multiple enumeration types appear in the same scope with duplicate enumerator names.23 \section{Enumerator Visibility} 24 \label{s:EnumeratorVisibility} 25 26 In C, unscoped enumerators present a \newterm{naming problem} when multiple enumeration types appear in the same scope with duplicate enumerator names. 27 27 There is no mechanism in C to resolve these naming conflicts other than renaming one of the duplicates, which may be impossible. 28 28 … … 33 33 enum E1 { First, Second, Third, Fourth }; 34 34 enum E2 { @Fourth@, @Third@, @Second@, @First@ }; $\C{// same enumerator names}$ 35 E1 p() { return Third; } $\C{// correctly resolved duplicate names}$35 E1 p() { return Third; } $\C{// return}$ 36 36 E2 p() { return Fourth; } 37 37 void foo() { … … 54 54 enum RGB @!@ { Red, Green, Blue }; 55 55 \end{cfa} 56 Now the enumerators \emph{must} be qualified with the associated enumeration .56 Now the enumerators \emph{must} be qualified with the associated enumeration type. 57 57 \begin{cfa} 58 58 Week week = @Week.@Mon; … … 68 68 } 69 69 \end{cfa} 70 As in Section~\ref{s:Enumerator Unscoping}, opening multiple scoped enumerations in a @with@ can result in duplicate enumeration names, but \CFA implicit type resolution and explicit qualification/casting handlesambiguities.70 As in Section~\ref{s:EnumeratorVisibility}, opening multiple scoped enumerations in a @with@ can result in duplicate enumeration names, but \CFA implicit type resolution and explicit qualification/casting handle ambiguities. 71 71 72 72 … … 243 243 \end{cfa} 244 244 which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicase @case@ clauses. 245 To better match with programmer intuition, \CFA toggles between value and position semantics dep neding on the language context.245 To better match with programmer intuition, \CFA toggles between value and position semantics depending on the language context. 246 246 For conditional clauses and switch statments, \CFA uses the robust position implementation. 247 247 \begin{cfa} -
doc/theses/jiada_liang_MMath/background.tex
r07e9df1 rec20ab9 74 74 However, it is restricted to integral values. 75 75 \begin{clang} 76 enum { Size = 20, Max = 10, MaxPlus10 = Max + 10, Max10Plus1, Fred = -7 };76 enum { Size = 20, Max = 10, MaxPlus10 = Max + 10, @Max10Plus1@, Fred = -7 }; 77 77 \end{clang} 78 78 Here, the aliased constants are: 20, 10, 20, 21, and -7. 79 79 Direct initialization is by a compile-time expression generating a constant value. 80 An enumerator without initializationis \newterm{auto-initialized}: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@.80 Indirect initialization (without initialization, @Max10Plus1@) is \newterm{auto-initialized}: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 81 81 Because multiple independent enumerators can be combined, enumerators with the same values can occur. 82 82 The enumerators are rvalues, so assignment is disallowed. … … 88 88 \begin{cfa} 89 89 typedef struct /* unnamed */ { ... } S; 90 struct /* unnamed */ { ... } x, y, z; 90 struct /* unnamed */ { ... } x, y, z; $\C{// questionable}$ 91 91 struct S { 92 union /* unnamed */ { 92 union /* unnamed */ { $\C{// unscoped fields}$ 93 93 int i; double d ; char ch; 94 94 }; … … 107 107 enum Week { 108 108 Thu@ = 10@, Fri, Sat, Sun, 109 Mon@ = 0@, Tue, Wed@,@ }; // terminating comma 109 Mon@ = 0@, Tue, Wed@,@ $\C{// terminating comma}$ 110 }; 110 111 \end{clang} 111 112 Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma.\footnote{ -
doc/theses/jiada_liang_MMath/intro.tex
r07e9df1 rec20ab9 135 135 136 136 \subsection{Algebraic Data Type} 137 \label{s:AlgebraicDataType} 137 138 138 139 An algebraic data type (ADT)\footnote{ADT is overloaded with abstract data type.} is another language feature often linked with enumeration, where an ADT conjoins an arbitrary type, possibly a \lstinline[language=C++]{class} or @union@, and a named constructor. -
doc/theses/jiada_liang_MMath/relatedwork.tex
r07e9df1 rec20ab9 18 18 \end{comment} 19 19 20 Enumeration-like features exist in many popular programming languages, both past and present, \eg Pascal~\cite{Pascal}, Ada~\cite{Ada}, \Csharp~\cite{Csharp}, OCaml~\cite{OCaml} \CC, Go~\cite{Go}, Haskell~\cite{Haskell}, Java~\cite{Java}, Modula-3~\cite{Modula-3},Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}.20 Enumeration-like features exist in many popular programming languages, both past and present, \eg Pascal~\cite{Pascal}, Ada~\cite{Ada}, \Csharp~\cite{Csharp}, OCaml~\cite{OCaml} \CC, Go~\cite{Go}, Haskell~\cite{Haskell}, Java~\cite{Java}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}. 21 21 Among theses languages, there are a large set of overlapping features, but each language has its own unique extensions and restrictions. 22 22 … … 24 24 \label{s:Pascal} 25 25 26 Classic Pascal hasthe \lstinline[language=Pascal]{const} aliasing declaration binding a name to a constant literal/expression.26 Classic Pascal introduced the \lstinline[language=Pascal]{const} aliasing declaration binding a name to a constant literal/expression. 27 27 \begin{pascal} 28 28 const one = 0 + 1; Vowels = set of (A,E,I,O,U); NULL = NIL; … … 62 62 type Traffic_Light is ( @Red@, Yellow, @Green@ ); 63 63 \end{ada} 64 Like \CFA, Ada uses a n advanced type-resolution algorithm, including the left-hand side of assignment,to disambiguate among overloaded identifiers.64 Like \CFA, Ada uses a type-resolution algorithm including the left-hand side of assignmente to disambiguate among overloaded identifiers. 65 65 \VRef[Figure]{f:AdaEnumeration} shows how ambiguity is handled using a cast, \ie \lstinline[language=ada]{RGB'(Red)}. 66 66 … … 97 97 Ada provides an alias mechanism, \lstinline[language=ada]{renames}, for aliasing types, which is useful to shorten package identifiers. 98 98 \begin{ada} 99 OtherRed: RGB renames Red;99 @OtherRed@ : RGB renames Red; 100 100 \end{ada} 101 101 which suggests a possible \CFA extension to @typedef@. … … 160 160 Hence, the ordering of the enumerators is crucial to provide the necessary ranges. 161 161 162 An enumeration type can be used in the Ada \lstinline[language=ada]{case} (all enumerators must appear or a default) or iterating constructs.162 An enumeration type can be used in the Ada \lstinline[language=ada]{case} (all enumerators must appear or a @default@) or iterating constructs. 163 163 \begin{cquote} 164 164 \setlength{\tabcolsep}{15pt} … … 241 241 whereas C @const@ declarations without @static@ are marked @R@. 242 242 243 The following \CC non-backwards compatible changes are made \see{\cite[\S~7.2]{ANSI98: C++}}.243 The following \CC non-backwards compatible changes are made \see{\cite[\S~7.2]{ANSI98:c++}}. 244 244 \begin{cquote} 245 245 Change: \CC objects of enumeration type can only be assigned values of the same enumeration type. … … 248 248 \begin{c++} 249 249 enum color { red, blue, green }; 250 color c = 1; $\C{// valid C, invalid C++}$250 color c = 1; $\C{// valid C, invalid c++}$ 251 251 \end{c++} 252 252 \textbf{Rationale}: The type-safe nature of \CC. \\ … … 263 263 enum e { A }; 264 264 sizeof(A) == sizeof(int) $\C{// in C}$ 265 sizeof(A) == sizeof(e) $\C{// in C++}$265 sizeof(A) == sizeof(e) $\C{// in c++}$ 266 266 /* and sizeof(int) is not necessary equal to sizeof(e) */ 267 267 \end{c++} … … 279 279 int i = A; i = e; $\C{// implicit casts to int}$ 280 280 \end{c++} 281 \CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), where the enumerators are accessed using type qualification. 281 \CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct})\footnote{ 282 The use of keyword \lstinline[language=c++]{class} is resonable because default visibility is \lstinline[language=c++]{private} (scoped). 283 However, default visibility for \lstinline[language=c++]{struct} is \lstinline[language=c++]{public} (unscoped) making it an odd choice.}, 284 where the enumerators are accessed using type qualification. 282 285 \begin{c++} 283 286 enum class E { A, B, C }; … … 291 294 E e = A; e = B; $\C{// direct access}$ 292 295 \end{c++} 293 \CC{11} added the ability to explicitly declare theunderlying \emph{integral} type for \lstinline[language=c++]{enum class}.296 \CC{11} added the ability to explicitly declare only an underlying \emph{integral} type for \lstinline[language=c++]{enum class}. 294 297 \begin{c++} 295 298 enum class RGB @: long@ { Red, Green, Blue }; … … 302 305 char ch = rgb::Red; ch = crgb; $\C{// error}$ 303 306 \end{c++} 304 Finally, enumerations can be used in the @switch@ statement but there is no mechanism to iterate through an enumeration. 305 An enumeration type cannot declare an array dimension but can be used as a subscript. 306 There is no mechanism to subtype or inherit from enumerations. 307 An enumeration can be used in the @if@ and @switch@ statements. 308 \begin{cquote} 309 \setlength{\tabcolsep}{15pt} 310 \begin{tabular}{@{}ll@{}} 311 \begin{c++} 312 if ( @day@ <= Fri ) 313 cout << "weekday" << endl; 314 315 316 317 318 \end{c++} 319 & 320 \begin{c++} 321 switch ( @day@ ) { 322 case Mon: case Tue: case Wed: case Thu: case Fri: 323 cout << "weekday" << endl; break; 324 case Sat: case Sun: 325 cout << "weekend" << endl; break; 326 } 327 \end{c++} 328 \end{tabular} 329 \end{cquote} 330 However, there is no mechanism to iterate through an enumeration without an unsafe cast and it does not understand the enumerator values. 331 \begin{c++} 332 enum Week { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun }; 333 for ( Week d = Mon; d <= Sun; d = @(Week)(d + 1)@ ) cout << d << ' '; 334 0 1 2 @3 4 5 6 7 8 9@ 10 11 12 13 335 \end{c++} 336 An enumeration type cannot declare an array dimension but an enumerator can be used as a subscript. 337 There is no mechanism to subtype or inherit from an enumeration. 307 338 308 339 … … 311 342 312 343 % https://www.tutorialsteacher.com/codeeditor?cid=cs-mk8Ojx 313 314 \Csharp is a dynamically-typed programming-language with a scoped, integral enumeration-type similar to the C/\CC enumeration. 344 % https://learn.microsoft.com/en-us/dotnet/api/system.enum?view=net-8.0 345 % https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/enums 346 347 \Csharp is a dynamically-typed programming-language with a scoped, integral enumeration similar to \CC \lstinline[language=C++]{enum class}. 315 348 \begin{csharp} 316 enum Weekday : byte { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun@,@ }; 349 enum Week : @long@ { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun@,@ } // terminating comma 350 enum RGB { Red, Green, Blue } 317 351 \end{csharp} 318 The default underlying type is @int@, with auto-incrementing, implicit/explicit initialization, terminator comma, and optional integral typing (default @int@).319 A method cannot be defined in an enumeration type .320 As well, there is an explicit bidirectional conversion between an enumeration and its integral type, and an implicit conversion to the enumerator label in display contexts.352 The default underlying integral type is @int@ (no @char@), with auto-incrementing, implicit/explicit initialization, and terminating comma. 353 A method cannot be defined in an enumeration type (extension methods are possible). 354 There is an explicit bidirectional conversion between an enumeration and its integral type, and an implicit conversion to the enumerator label in display contexts. 321 355 \begin{csharp} 322 int day = (int)Weekday.Fri; $\C{// day == 10}$ 323 Weekday weekday = (Weekdays)42; $\C{// weekday == 42, logically invalid}$ 324 Console.WriteLine( Weekday.Fri ); $\C{// print Fri}$ 325 string mon = Weekday.Mon.ToString(); $\C{// mon == "Mon"}$ 356 int iday = (int)Week.Fri; $\C{// day == 11}$ 357 Week day = @(Week)@42; $\C{// day == 42, unsafe}$ 358 string mon = Week.Mon.ToString(); $\C{// mon == "Mon"}$ 359 RGB rgb = RGB.Red; $\C{// rgb == "Red"}$ 360 day = @(Week)@rgb; $\C{// day == "Mon", unsafe}$ 361 Console.WriteLine( Week.Fri ); $\C{// print label Fri}$ 326 362 \end{csharp} 327 328 The @Enum.GetValues@ pseudo-method retrieves an array of the enumeration constants for looping over an enumeration type or variable (expensive operation). 363 The majority of the integral operators (relational and arithmetic) work with enumerations, except @*@ and @/@. 329 364 \begin{csharp} 330 foreach ( Weekday constant in @Enum.GetValues@( typeof(Weekday) ) ) { 331 Console.WriteLine( constant + " " + (int)constant ); // label, position 332 } 365 day = day++ - 5; $\C{// unsafe}$ 366 day = day & day; 333 367 \end{csharp} 334 368 335 The @Flags@ attribute creates a bit-flags enumeration, allowing bitwise operators @&@, @|@, @~@ (complement), @^@ (xor). 369 An enumeration can be used in the @if@ and @switch@ statements. 370 \begin{cquote} 371 \setlength{\tabcolsep}{15pt} 372 \begin{tabular}{@{}ll@{}} 336 373 \begin{csharp} 337 @[Flags]@ public enum Weekday { 338 None = 0x0, Mon = 0x1, Tue = 0x2, Wed = 0x4, 339 Thu = 0x8, Fri = 0x10, Sat = 0x20, Sun = 0x40, 340 Weekend = @Sat | Sun@, 341 Weekdays = @Mon | Tue | Wed | Thu | Fri@ 342 } 343 Weekday meetings = @Weekday.Mon | Weekday.Wed@; // 0x5 344 \end{csharp} 345 346 \VRef[Figure]{CsharpFreeVersusClass} shows an enumeration with free routines for manipulation, and embedding the enumeration and operations into an enumeration class. 347 The key observation is that an enumeration class is just a structuring mechanism without any additional semantics. 348 349 % https://learn.microsoft.com/en-us/dotnet/api/system.enum?view=net-8.0 350 351 \begin{figure} 352 \centering 353 \begin{tabular}{@{}l|l@{}} 354 \multicolumn{1}{@{}c|}{non-object oriented} & \multicolumn{1}{c@{}}{object oriented} \\ 355 \hline 356 \begin{csharp} 357 public class Program { 358 359 enum Weekday { 360 Mon, Tue, Wed, Thu, Fri, Sat, Sun }; 361 362 static bool isWeekday( Weekday wd ) { 363 return wd <= Weekday.Fri; 364 } 365 static bool isWeekend( Weekday wd ) { 366 return Weekday.Sat <= wd; 367 } 368 369 370 public static void Main() { 371 Weekday day = Weekday.Sat; 372 373 Console.WriteLine( isWeekday( day ) ); 374 Console.WriteLine( isWeekend( day ) ); 375 } 376 } 374 if ( @day@ <= Week.Fri ) 375 Console.WriteLine( "weekday" ); 376 377 378 379 380 377 381 \end{csharp} 378 382 & 379 383 \begin{csharp} 380 public class Program { 381 public @class@ WeekDay : Enumeration { 382 public enum Day { 383 Mon, Tue, Wed, Thu, Fri, Sat, Sun }; 384 public enum Day2 : Day { 385 XXX, YYY }; 386 Day day; 387 public bool isWeekday() { 388 return day <= Day.Fri; 389 } 390 public bool isWeekend() { 391 return day > Day.Fri; 392 } 393 public WeekDay( Day d ) { day = d; } 394 } 395 public static void Main() { 396 WeekDay cday = new 397 WeekDay( WeekDay.Day.Sat ); 398 Console.WriteLine( cday.isWeekday() ); 399 Console.WriteLine( cday.isWeekend() ); 400 } 384 switch ( @day@ ) { 385 case Week.Mon: case Week.Tue: case Week.Wed: 386 case Week.Thu: case Week.Fri: 387 Console.WriteLine( "weekday" ); break; 388 case Week.Sat: case Week.Sun: 389 Console.WriteLine( "weekend" ); break; 401 390 } 402 391 \end{csharp} 403 392 \end{tabular} 404 \caption{\Csharp: Free Routine Versus Class Enumeration} 405 \label{CsharpFreeVersusClass} 406 \end{figure} 393 \end{cquote} 394 However, there is no mechanism to iterate through an enumeration without an unsafe cast to increment and positions versus values is not handled. 395 \begin{csharp} 396 for ( Week d = Mon; d <= Sun; @d += 1@ ) { 397 Console.Write( d + " " ); 398 } 399 Mon Tue Wed @3 4 5 6 7 8 9@ Thu Fri Sat Sun 400 \end{csharp} 401 The @Enum.GetValues@ pseudo-method retrieves an array of the enumeration constants for looping over an enumeration type or variable (expensive operation). 402 \begin{csharp} 403 foreach ( Week d in @Enum.GetValues@( typeof(Week) ) ) { 404 Console.WriteLine( d + " " + (int)d + " " ); // label, position 405 } 406 Mon 0, Tue 1, Wed 2, Thu 10, Fri 11, Sat 12, Sun 13, 407 \end{csharp} 408 409 An enumeration type cannot declare an array dimension but an enumerator can be used as a subscript. 410 There is no mechanism to subtype or inherit from an enumeration. 411 412 The @Flags@ attribute creates a bit-flags enumeration, making bitwise operators @&@, @|@, @~@ (complement), @^@ (xor) sensible. 413 \begin{csharp} 414 @[Flags]@ public enum Week { 415 None = 0x0, Mon = 0x1, Tue = 0x2, Wed = 0x4, 416 Thu = 0x8, Fri = 0x10, Sat = 0x20, Sun = 0x40, 417 Weekdays = @Mon | Tue | Wed | Thu | Fri@ $\C{// Weekdays == 0x1f}$ 418 Weekend = @Sat | Sun@, $\C{// Weekend == 0x60}$ 419 } 420 Week meetings = @Week.Mon | Week.Wed@; $\C{// 0x5}$ 421 \end{csharp} 407 422 408 423 409 424 \section{Golang} 410 425 411 Golang provides pseudo-enumeration similar to classic Pascal \lstinline[language=pascal]{const}, binding a name to a constant literal/expression. 426 Golang has a no enumeration. 427 It has @const@ aliasing declarations, similar to \CC \see{\VRef{s:C++RelatedWork}}, for basic types with type inferencing and static initialization (constant expression). 412 428 \begin{Go} 413 const ( R = 0; G; B ) $\C{// implicit: 0 0 0}$ 414 const ( Fred = "Fred"; Mary = "Mary"; Jane = "Jane" ) $\C{// explicit: Fred Mary Jane}$ 429 const R @int@ = 0; const G @uint@ = 1; const B = 2; $\C{// explicit typing and type inferencing}$ 430 const Fred = "Fred"; const Mary = "Mary"; const Jane = "Jane"; 431 const S = 0; const T = 0; 432 const USA = "USA"; const U = "USA"; 433 const V = 3.1; const W = 3.1; 434 \end{Go} 435 Since these declarations are unmutable variables, they are unscoped and Golang has no overloading. 436 437 Golang provides an enumeration-like feature to group together @const@ declaration into a block and introduces a form of auto-initialization. 438 \begin{Go} 439 const ( R = 0; G; B ) $\C{// implicit initialization: 0 0 0}$ 440 const ( Fred = "Fred"; Mary = "Mary"; Jane = "Jane" ) $\C{// explicit initialization: Fred Mary Jane}$ 415 441 const ( S = 0; T; USA = "USA"; U; V = 3.1; W ) $\C{// type change, implicit/explicit: 0 0 USA USA 3.1 3.1}$ 416 442 \end{Go} 417 Constant identifiers are unscoped and must be unique (no overloading). 418 The first enumerator \emph{must} be explicitly initialized; 419 subsequent enumerators can be implicitly or explicitly initialized. 420 Implicit initialization is the previous (predecessor) enumerator value. 421 422 Auto-incrementing is supported by the keyword \lstinline[language=Go]{iota}, available only in the \lstinline[language=Go]{const} declaration. 423 The \lstinline[language=Go]{iota} is a \emph{per \lstinline[language=golang]{const} declaration} integer counter, starting at zero and implicitly incremented by one for each \lstinline[language=golang]{const} identifier (enumerator). 443 The first identifier \emph{must} be explicitly initialized; 444 subsequent identifiers can be implicitly or explicitly initialized. 445 Implicit initialization is the \emph{previous} (predecessor) identifier value. 446 447 Each @const@ declaration provides an implicit integer counter starting at zero, called \lstinline[language=Go]{iota}. 448 Using \lstinline[language=Go]{iota} outside of a @const@ block always sets the identifier to zero. 449 \begin{Go} 450 const R = iota; $\C{// 0}$ 451 \end{Go} 452 Inside a @const@ block, \lstinline[language=Go]{iota} is implicitly incremented for each \lstinline[language=golang]{const} identifier and used to initialize the next uninitialized identifier. 424 453 \begin{Go} 425 454 const ( R = @iota@; G; B ) $\C{// implicit: 0 1 2}$ … … 430 459 const ( O1 = iota + 1; @_@; O3; @_@; O5 ) // 1, 3, 5 431 460 \end{Go} 432 Auto-in crementing stops after an explicit initialization.461 Auto-initialization reverts from \lstinline[language=Go]{iota} to the previous value after an explicit initialization, but auto-incrementing of \lstinline[language=Go]{iota} continues. 433 462 \begin{Go} 434 463 const ( Mon = iota; Tue; Wed; // 0, 1, 2 435 @Thu = 10@; Fri; Sat; Sun ) // 10, 10, 10, 10464 @Thu = 10@; Fri; Sat; Sun = itoa ) // 10, 10, 10, 6 436 465 \end{Go} 437 Auto-in crementing can be restarted with an expression containing\emph{one} \lstinline[language=Go]{iota}.466 Auto-initialization from \lstinline[language=Go]{iota} is restarted and \lstinline[language=Go]{iota} reinitialized with an expression containing as most \emph{one} \lstinline[language=Go]{iota}. 438 467 \begin{Go} 439 const ( V1 = iota; V2; @V3 = 7;@ V4 = @iota@ ; V5 ) // 0 1 7 3 4468 const ( V1 = iota; V2; @V3 = 7;@ V4 = @iota@ + 1; V5 ) // 0 1 7 4 5 440 469 const ( Mon = iota; Tue; Wed; // 0, 1, 2 441 @Thu = 10;@ Fri = @iota - Wed + Thu - 1@; Sat; Sun ) // 10, 11, 12, 13470 @Thu = 10;@ Fri = @iota - Wed + Thu - 1@; Sat; Sun ) // 10, 11, 12, 13 442 471 \end{Go} 443 Note, \lstinline[language=Go]{iota} is advanced for an explicitly initialized enumerator, like the underscore @_@ identifier. 472 Here, @V4@ and @Fri@ restart auto-incrementing from \lstinline[language=Go]{iota} and reset \lstinline[language=Go]{iota} to 4 and 11, respectively, because of the intialization expressions containing \lstinline[language=Go]{iota}. 473 Note, because \lstinline[language=Go]{iota} is incremented for an explicitly initialized identifier or @_@, 474 at @Fri@ \lstinline[language=Go]{iota} is 4 requiring the minus one to compute the value for @Fri@. 444 475 445 476 Basic switch and looping are possible. 446 477 \begin{cquote} 447 \setlength{\tabcolsep}{ 15pt}478 \setlength{\tabcolsep}{20pt} 448 479 \begin{tabular}{@{}ll@{}} 449 480 \begin{Go} 450 day := Mon; 451 switch day{481 day := Mon; // := $\(\Rightarrow\)$ type inferencing 482 switch @day@ { 452 483 case Mon, Tue, Wed, Thu, Fri: 453 484 fmt.Println( "weekday" ); … … 459 490 \begin{Go} 460 491 461 for i := Mon; i <= Sun; i += 1 {492 for i := @Mon@; i <= @Sun@; i += 1 { 462 493 fmt.Println( i ) 463 494 } … … 470 501 However, the loop prints the values from 0 to 13 because there is no actual enumeration. 471 502 503 A constant variable can be used as an array dimension or a subscript. 504 \begin{Go} 505 var ar[@Sun@] int 506 ar[@Mon@] = 3 507 \end{Go} 508 472 509 473 510 \section{Java} 474 511 475 Every enumeration in Java is an enumerationclass.476 For a basic enumeration 512 Java provides an enumeration using a specialized class. 513 A basic Java enumeration is an opaque enumeration, where the enumerators are constants. 477 514 \begin{Java} 478 enum Weekday { Mon, Tue, Wed, Thu, Fri, Sat, Sun }; 479 Weekday day = Weekday.Sat; 515 enum Week { 516 Mon, Tue, Wed, Thu, Fri, Sat, Sun; 517 } 518 Week day = Week.Sat; 480 519 \end{Java} 481 the scoped enumerators are an ordered list of @final@ methods of type integer, ordered left to right starting at 0, increasing by 1.482 The value of an enumeration instance is restricted to the enumeration's enumerators.483 There is an implicit @int@ variable in the enumeration used to store the value of an enumeration instance. 484 The position (ordinal) and label are accessible , where the value is the same as the position.520 The enumerators members are scoped and cannot be made \lstinline[language=java]{public}, hence require qualification. 521 The value of an enumeration instance is restricted to its enumerators. 522 523 The position (ordinal) and label are accessible but there is no value. 485 524 \begin{Java} 486 System.out.println( day.!ordinal()! + " " + day.!name()! ); // 5 Sat 525 System.out.println( day.!ordinal()! + " " + !day! + " " + day.!name()! ); 526 5 Sat Sat 487 527 \end{Java} 488 There is an inverse function @valueOf@ from string to enumerator. 528 Since @day@ has no value, it prints its label (name). 529 The member @valueOf@ is the inverse of @name@ converting a string to enumerator. 489 530 \begin{Java} 490 day = Week day.valueOf( "Wed" );531 day = Week.valueOf( "Wed" ); 491 532 \end{Java} 492 There are no implicit conversions to/from an enumerator and its underlying type. 493 Like \Csharp, \VRef[Figure]{f:JavaFreeVersusClass} shows the same example for an enumeration with free routines for manipulation, and embedding the enumeration and operations into an enumeration class. 494 495 \begin{figure} 496 \centering 497 \begin{tabular}{@{}l|l@{}} 498 \multicolumn{1}{@{}c|}{non-object oriented} & \multicolumn{1}{c@{}}{object oriented} \\ 499 \hline 533 Extra members can be added to provide specialized operations. 500 534 \begin{Java} 501 enum Weekday !{! 502 Mon, Tue, Wed, Thu, Fri, Sat, Sun !}!; 503 504 static boolean isWeekday( Weekday wd ) { 505 return wd.ordinal() <= Weekday.Fri.ordinal(); 506 } 507 static boolean isWeekend( Weekday wd ) { 508 return Weekday.Fri.ordinal() < wd.ordinal(); 509 } 510 511 public static void main( String[] args ) { 512 Weekday day = Weekday.Sat; 513 System.out.println( isWeekday( day ) ); 514 System.out.println( isWeekend( day ) ); 515 } 535 public boolean isWeekday() { return !ordinal()! <= Fri.ordinal(); } 536 public boolean isWeekend() { return Fri.ordinal() < !ordinal()!; } 537 \end{Java} 538 Notice the unqualified calls to @ordinal@ in the members implying a \lstinline[language=Java]{this} to some implicit implementation variable, likely an @int@. 539 540 Enumerator values require an enumeration type (any Java type may be used) and implementation member. 541 \begin{Java} 542 enum Week { 543 Mon!(1)!, Tue!(2)!, Wed!(3)!, Thu!(4)!, Fri!(5)!, Sat!(6)!, Sun!(7)!; // must appear first 544 private !long! day; $\C{// enumeration type and implementation member}$ 545 private Week( !long! d ) { day = d; } $\C{// enumerator initialization}$ 546 }; 547 Week day = Week.Sat; 548 \end{Java} 549 The position, value, and label are accessible. 550 \begin{Java} 551 System.out.println( !day.ordinal()! + " " + !day.day! + " " + !day.name()! ); 552 5 6 Sat 553 \end{Java} 554 If the implementation member is \lstinline[language=Java]{public}, the enumeration is unsafe, as any value of the underlying type can be assigned to it, \eg @day = 42@. 555 The implementation constructor must be private since it is only used internally to initialize the enumerators. 556 Initialization occurs at the enumeration-type declaration for each enumerator in the first line. 557 558 Enumerations can be used in the @if@ and @switch@ statements but only for equality tests. 559 \begin{cquote} 560 \setlength{\tabcolsep}{15pt} 561 \begin{tabular}{@{}ll@{}} 562 \begin{Java} 563 if ( !day! == Week.Fri ) 564 System.out.println( "Fri" ); 565 566 567 568 516 569 \end{Java} 517 570 & 518 571 \begin{Java} 519 enum Weekday !{! 520 Mon, Tue, Wed, Thu, Fri, Sat, Sun; 521 522 public boolean isWeekday() { 523 return ordinal() <= Weekday.Fri.ordinal(); 524 } 525 public boolean isWeekend() { 526 return Weekday.Fri.ordinal() < ordinal(); 527 } 528 !}! 529 public static void main( String[] args ) { 530 WeekDay day = WeekDay.Sat; 531 System.out.println( day.isWeekday() ); 532 System.out.println( day.isWeekend() ); 572 switch ( !day! ) { 573 case Mon: case Tue: case Wed: case Thu: case Fri: 574 System.out.println( "weekday" ); break; 575 case Sat: case Sun: 576 System.out.println( "weekend" ); break; 533 577 } 534 578 \end{Java} 535 579 \end{tabular} 536 \ caption{Java: Free Routine Versus Class Enumeration}537 \label{f:JavaFreeVersusClass} 538 \end{figure} 539 540 To explicitly assign enumerator values and/or use a non-@int@ enumeration type (any Java type may be used), the enumeration must specify an explicit type in the enumeration class and a constructor.580 \end{cquote} 581 Notice enumerators in the @switch@ statement do not require qualification. 582 583 There are no arithemtic operations on enumerations, so there is no arithmetic way to iterate through an enumeration without making the implementation type \lstinline[language=Java]{public}. 584 Like \Csharp, looping over an enumeration is done using method @values@, which returns an array of enumerator values (expensive operation). 541 585 \begin{Java} 542 enum Weekday { 543 Mon!(1)!, Tue!(2)!, Wed!(3)!, Thu!(4)!, Fri!(5)!, Sat!(6)!, Sun!(7)!; // must appear first 544 private !long! day; $\C{// underlying enumeration type}$ 545 private Weekday( !long! d ) { day = d; } $\C{// used to initialize enumerators}$ 546 }; 547 Weekday day = Weekday.Sat; 548 \end{Java} 549 If an enumerator initialization is a runtime expression, the expression is executed once at the point the enumeration is declaraed. 550 551 The position, value, and label are accessible. 552 \begin{Java} 553 System.out.println( !day.ordinal()! + " " + !day.day! + " " + !day.name()! ); // 5 6 Sat 554 \end{Java} 555 The constructor is private so only initialization or assignment can be used to set an enumeration, which ensures only corresponding enumerator values are allowed. 556 557 An enumeration can appear in a @switch@ statement, but no ranges. 558 \begin{Java} 559 switch ( day ) { 560 case Mon: case Tue: case Wed: case Thu: case Fri: 561 System.out.println( "weekday" ); 562 break; 563 case Sat: case Sun: 564 System.out.println( "weekend" ); 565 break; 566 } 567 \end{Java} 568 Like \Csharp, looping over an enumeration is done using method @values@, which returns the array of enumerator values (expensive operation). 569 \begin{Java} 570 for ( Weekday iday : Weekday.values() ) { 571 System.out.print( iday.ordinal() + iday.day + " " + iday.name() + ", " ); 586 for ( Week d : Week.values() ) { 587 System.out.print( d.ordinal() + d.day + " " + d.name() + ", " ); 572 588 } 573 589 0 1 Mon, 1 2 Tue, 2 3 Wed, 3 4 Thu, 4 5 Fri, 5 6 Sat, 6 7 Sun, 574 590 \end{Java} 575 591 576 As well, Java provides an @EnumSet@ where the underlying type is an efficient set of bits, one per enumeration \see{\Csharp \lstinline{Flags}, \VRef{s:Csharp}}, providing (logical) operations on groups of enumerators. 592 An enumeration type cannot declare an array dimension nor can an enumerator be used as a subscript. 593 Enumeration inheritence is disallowed because an enumeration is \lstinline[language=Java]{final}. 594 595 Java provides an @EnumSet@ where the underlying type is an efficient set of bits, one per enumeration \see{\Csharp \lstinline{Flags}, \VRef{s:Csharp}}, providing (logical) operations on groups of enumerators. 577 596 There is also a specialized version of @HashMap@ with enumerator keys, which has performance benefits. 578 597 579 Enumeration inheritence is disallowed because an enumeration is @final@.580 581 582 583 \section{Modula-3}584 585 586 598 587 599 \section{Rust} 600 588 601 % https://doc.rust-lang.org/reference/items/enumerations.html 589 602 590 Rust provides a scoped enumeration based on variant types. 591 % An enumeration, also referred to as an enum, is a simultaneous definition of a nominal enumerated type as well as a set of constructors, that can be used to create or pattern-match values of the corresponding enumerated type. 592 An enumeration without constructors is called field-less. 603 Rust @enum@ provides two largely independent mechanisms: an ADT and an enumeration. 604 When @enum@ is an ADT, pattern matching is used to discriminate among the variant types. 605 \begin{cquote} 606 \sf\setlength{\tabcolsep}{20pt} 607 \begin{tabular}{@{}ll@{}} 593 608 \begin{rust} 594 enum Week { Mon, Tues, Wed, Thu, Fri, Sat, Sun@,@ } 595 let mut week: Week = Week::Mon; 596 week = Week::Fri; 609 struct S { 610 i : isize, j : isize 611 } 612 enum @ADT@ { 613 I(isize), // int 614 F(f64), // float 615 S(S), // struct 616 } 597 617 \end{rust} 598 A field-less enumeration with only unit variants is called unit-only. 618 & 599 619 \begin{rust} 600 enum Week { Mon = 0, Tues = 1, Wed = 2, Thu = 3, Fri = 4, Sat = 5, Sun = 6 } 620 let mut s = S{ i : 3, j : 4 }; 621 let mut adt : ADT; 622 adt = ADT::I(3); adt = ADT::F(3.5); adt = ADT::S(s); // init examples 623 @match@ adt { 624 ADT::I(i) => println!( "{:?}", i ), 625 ADT::F(f) => println!( "{:?}", f ), 626 ADT::S(s) => println!( "{:?} {:?}", s.i, s.j ), 627 } 601 628 \end{rust} 602 Enum constructors can have either named or unnamed fields:603 \begin{rust}604 enum Animal {605 Dog( String, f64 ),606 Cat{ name: String, weight: f64 },607 }608 let mut a: Animal = Animal::Dog("Cocoa".to_string(), 37.2);609 a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 };610 \end{rust}611 Here, @Dog@ is an @enum@ variant, whereas @Cat@ is a struct-like variant.612 613 Each @enum@ type has an implicit integer tag (discriminant), with a unique value for each variant type.614 Like a C enumeration, the tag values for the variant types start at 0 with auto incrementing.615 The tag is re-purposed for enumeration by allowing it to be explicitly set, and auto incrmenting continues from that value.616 \begin{cquote}617 \sf\setlength{\tabcolsep}{3pt}618 \begin{tabular}{rcccccccr}619 @enum@ Week \{ & Mon, & Tue, & Wed = 2, & Thu = 10, & Fri, & Sat = 5, & Sun & \}; \\620 \rm tags & 0 & 1 & 2 & 10 & 11 & 5 & 6 & \\621 629 \end{tabular} 622 630 \end{cquote} 623 In general, the tag can only be read as an opaque reference for comparison.631 When the variant types are the unit type, the ADT is still not an enumeration because there is no enumerating \see{\VRef{s:AlgebraicDataType}}. 624 632 \begin{rust} 625 if mem::discriminant(&week) == mem::discriminant(&Week::Mon) ... 633 enum Week { Mon, Tues, Wed, Thu, Fri, Sat, Sun@,@ } // terminating comma 634 let mut week : Week = Week::Mon; 635 match week { 636 Week::Mon => println!( "Mon" ), 637 ... 638 Week::Sun => println!( "Sun" ), 639 } 626 640 \end{rust} 627 If the enumeration is unit-only, or field-less with no explicit discriminants and where only unit variants are explicit, then the discriminant is accessible with a numeric cast. 641 642 However, Rust allows direct setting of the ADT constructor, which means it is actually a tag. 643 \begin{cquote} 644 \sf\setlength{\tabcolsep}{15pt} 645 \begin{tabular}{@{}ll@{}} 628 646 \begin{rust} 629 if week as isize == Week::Mon as isize ... 647 enum Week { 648 Mon, Tues, Wed, // start 0 649 Thu @= 10@, Fri, 650 Sat, Sun, 651 } 652 630 653 \end{rust} 654 & 655 \begin{rust} 656 #[repr(u8)] 657 enum ADT { 658 I(isize) @= 5@, // ??? 659 F(f64) @= 10@, 660 S(S) @= 0@, 661 } 662 \end{rust} 663 \end{tabular} 664 \end{cquote} 665 Through this integral tag, it is possible to enumerate, and when all tags represent the unit type, it behaves like \CC \lstinline[language=C++]{enum class}. 666 When tags represent non-unit types, Rust largely precludes accessing the tag because the semantics become meaningless. 667 Hence, the two mechanisms are largely disjoint, and ony the enumeration component is discussed. 668 669 In detail, the @enum@ type has an implicit integer tag (discriminant), with a unique value for each variant type. 670 Direct initialization is by a compile-time expression generating a constant value. 671 Indirect initialization (without initialization, @Fri@/@Sun@) is auto-initialized: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 672 There is an explicit cast from the tag to integer. 673 \begin{rust} 674 let mut mon : isize = Week::Mon as isize; 675 \end{rust} 676 An enumeration can be used in the @if@ and \lstinline[language=rust]{match} (@switch@) statements. 677 \begin{cquote} 678 \setlength{\tabcolsep}{8pt} 679 \begin{tabular}{@{}ll@{}} 680 \begin{c++} 681 if @week as isize@ == Week::Mon as isize { 682 println!( "{:?}", week ); 683 } 684 685 686 \end{c++} 687 & 688 \begin{c++} 689 match @week@ { 690 Week::Mon | Week:: Tue | Week::Wed | Week::Thu 691 | Week::Fri => println!( "weekday" ), 692 Week::Sat | Week:: Sun => println!( "weekend" ), 693 } 694 \end{c++} 695 \end{tabular} 696 \end{cquote} 697 However, there is no mechanism to iterate through an enumeration without an casting to integral and positions versus values is not handled. 698 \begin{c++} 699 for d in Week::Mon as isize ..= Week::Sun as isize { 700 print!( "{:?} ", d ); 701 } 702 0 1 2 @3 4 5 6 7 8 9@ 10 11 12 13 703 \end{c++} 704 An enumeration type cannot declare an array dimension nor as a subscript. 705 There is no mechanism to subtype or inherit from an enumeration. 631 706 632 707 … … 2162 2237 A basic variant is a list of nullary datatype constructors, which is like an unscoped, opaque enumeration. 2163 2238 \begin{ocaml} 2164 type week day= Mon | Tue | Wed | Thu | Fri | Sat | Sun2165 let day : week day@= Mon@ $\C{(* bind *)}$2166 let take_class( d : week day) =2239 type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun 2240 let day : week @= Mon@ $\C{(* bind *)}$ 2241 let take_class( d : week ) = 2167 2242 @match@ d with $\C{(* matching *)}$ 2168 2243 Mon | Wed -> Printf.printf "CS442\n" | … … 2175 2250 The only operations are binding and pattern matching (equality), where the variant name is logically the implementation tag stored in the union for discriminating the value in the object storage. 2176 2251 After compilation, variant names are mapped to an opague ascending intergral type discriminants, starting from 0. 2177 Here, function @take_class@ has a @week day@ parameter, and returns @"CS442"@, if the weekdayvalue is @Mon@ or @Wed@, @"CS343"@, if the value is @Tue@ or @Thu@, and @"Tutorial"@ for @Fri@.2178 The ``@_@'' is a wildcard matching any @week day@ value, so the function returns @"Take a break"@ for values @Sat@ or @Sun@, which are not matched by the previous cases.2252 Here, function @take_class@ has a @week@ parameter, and returns @"CS442"@, if the week value is @Mon@ or @Wed@, @"CS343"@, if the value is @Tue@ or @Thu@, and @"Tutorial"@ for @Fri@. 2253 The ``@_@'' is a wildcard matching any @week@ value, so the function returns @"Take a break"@ for values @Sat@ or @Sun@, which are not matched by the previous cases. 2179 2254 Since the variant has no type, it has a \newterm{0-arity constructor}, \ie no parameters. 2180 Because @week day@ is a union of values @Mon@ to @Sun@, it is a \newterm{union type} in turns of the functional-programming paradigm.2255 Because @week@ is a union of values @Mon@ to @Sun@, it is a \newterm{union type} in turns of the functional-programming paradigm. 2181 2256 2182 2257 Each variant can have an associated heterogeneous type, with an n-ary constructor for creating a corresponding value. … … 2242 2317 term "tag" further. 2243 2318 2244 <<Because week dayis a summation of values Mon to Sun, it is a sum type in2319 <<Because week is a summation of values Mon to Sun, it is a sum type in 2245 2320 turns of the functional-programming paradigm>> 2246 2321 … … 2259 2334 > I've marked 3 places with your name to shows places with enum ordering. 2260 2335 > 2261 > type week day= Mon | Tue | Wed | Thu | Fri | Sat | Sun2262 > let day : week day= Mon2263 > let take_class( d : week day) =2336 > type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun 2337 > let day : week = Mon 2338 > let take_class( d : week ) = 2264 2339 > if d <= Fri then (* Gregor *) 2265 > Printf.printf "week day\n"2340 > Printf.printf "week\n" 2266 2341 > else if d >= Sat then (* Gregor *) 2267 2342 > Printf.printf "weekend\n"; … … 2474 2549 loop & & & & & & & & & & & & & \CM \\ 2475 2550 \hline 2476 array 2551 array/subscript & & & & & & & & & & & \CM & & \CM \\ 2477 2552 \hline 2478 2553 subtype & & & & & & & & & & & & & \CM \\
Note: See TracChangeset
for help on using the changeset viewer.