- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/relatedwork.tex
r508cff0 r29c8675 1 1 \chapter{Related Work} 2 2 \label{s:RelatedWork} 3 4 \begin{comment}5 An algebraic data type (ADT) can be viewed as a recursive sum of product types.6 A sum type lists values as members.7 A member in a sum type definition is known as a data constructor.8 For example, C supports sum types union and enumeration (enum).9 An enumeration in C can be viewed as the creation of a list of zero-arity data constructors.10 A union instance holds a value of one of its member types.11 Defining a union does not generate new constructors.12 The definition of member types and their constructors are from the outer lexical scope.13 14 In general, an \newterm{algebraic data type} (ADT) is a composite type, \ie, a type formed by combining other types.15 Three common classes of algebraic types are \newterm{array type}, \ie homogeneous types, \newterm{product type}, \ie heterogeneous tuples and records (structures), and \newterm{sum type}, \ie tagged product-types (unions).16 Enumerated 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.17 Values of algebraic types are access by subscripting, field qualification, or type (pattern) matching.18 \end{comment}19 3 20 4 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} \see{discussion in \VRef{s:AlgebraicDataType}}, Java~\cite{Java}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}. … … 45 29 type Boolean = ( false, true ); 46 30 \end{pascal} 47 The enumeration ordering supports the relational operators @=@, @<>@, @<@, @<=@, @>=@, and @>@, provided both operands are the same (sub)type.31 The enumeration supports the relational operators @=@, @<>@, @<@, @<=@, @>=@, and @>@, interpreted as as comparison in terms of declaration order. 48 32 49 33 The following auto-generated pseudo-functions exist for all enumeration types: … … 65 49 wend : Weekend; 66 50 \end{pascal} 67 Hence, the ordering of theenumerators is crucial to provide the necessary ranges.51 Hence, declaration order of enumerators is crucial to provide the necessary ranges. 68 52 There is a bidirectional assignment between the enumeration and its subranges. 69 53 \begin{pascal} … … 151 135 152 136 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. 153 The integral size can be explicitly specified using compiler directive @$PACKENUM@~$N$, where $N$ is the number of bytes, \eg:137 The integral size can be explicitly specified using compiler directive \$@PACKENUM@~$N$, where $N$ is the number of bytes, \eg: 154 138 \begin{pascal} 155 139 Type @{$\color{red}\$$PACKENUM 1}@ SmallEnum = ( one, two, three ); … … 199 183 \end{figure} 200 184 201 Enumerators without initialization are auto-initialized from left to right, starting at zero ,incrementing by 1.185 Enumerators without initialization are auto-initialized from left to right, starting at zero and incrementing by 1. 202 186 Enumerators with initialization must set \emph{all} enumerators in \emph{ascending} order, \ie there is no auto-initialization. 203 187 \begin{ada} … … 382 366 \end{c++} 383 367 \CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct})\footnote{ 384 The use of keyword \lstinline[language=c++]{class} is re sonable because default visibility is \lstinline[language=c++]{private} (scoped).368 The use of keyword \lstinline[language=c++]{class} is reasonable because default visibility is \lstinline[language=c++]{private} (scoped). 385 369 However, default visibility for \lstinline[language=c++]{struct} is \lstinline[language=c++]{public} (unscoped) making it an odd choice.}, 386 370 where the enumerators are accessed using type qualification. … … 396 380 E e = A; e = B; $\C{// direct access}$ 397 381 \end{c++} 398 \CC{11} added the ability to explicitly declare onlyan underlying \emph{integral} type for \lstinline[language=c++]{enum class}.382 \CC{11} added the ability to explicitly declare an underlying \emph{integral} type for \lstinline[language=c++]{enum class}. 399 383 \begin{c++} 400 384 enum class RGB @: long@ { Red, Green, Blue }; … … 430 414 \end{tabular} 431 415 \end{cquote} 432 However, there is no mechanism to iterate through an enumeration without an unsafe cast and it does not understand the enumerator values. 416 However, there is no mechanism to iterate through an enumeration. 417 A common workaround is to iterate over enumerator as integral values, but it only works if 418 enumerators resemble a sequence of natural, i.e., enumerators are auto-initialized. 419 Otherwises, the iteration would have integers that are not enumeration values. 433 420 \begin{c++} 434 421 enum Week { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun }; … … 449 436 % https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/enums 450 437 451 \Csharp is a dynamically-typedprogramming language with a scoped, integral enumeration similar to \CC \lstinline[language=C++]{enum class}.438 \Csharp is a programming language with a scoped, integral enumeration similar to \CC \lstinline[language=C++]{enum class}. 452 439 \begin{csharp} 453 440 enum Week : @long@ { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun } … … 508 495 \end{cquote} 509 496 510 To indirectly enumerate, \Csharp's Enum library has @Enum.GetValues@, a pseudo-method that retrieves an array of the enumeration constants for looping over an enumeration type or variable (expensive operation). 497 To indirectly enumerate, \Csharp's Enum library provides @Enum.GetValues@, 498 % a pseudo-method that retrieves an array of the enumeration constants for looping over an enumeration type or variable (expensive operation). 499 a static memeber of abstract Enum type that return a reference to an array of all enumeration constants. 500 Internally, a Enum type has a static member called @fieldInfoHash@, a @Hashtable@ that stores enumerators information. The field is populated on-demand: 501 it only contains information if a @reflection@ like @GetValues@ is called. But the information will be cached, so the cost of reflection is paid only 502 once throughout the lifetime of a program. @GetValues@ then converts a @Hashtable@ to an @Array@, which supports enumerating. 511 503 \begin{csharp} 512 504 foreach ( Week d in @Enum.GetValues@( typeof(Week) ) ) { … … 535 527 \label{s:Go} 536 528 537 Go has a no enumeration. 538 It has @const@ aliasing declarations, similar to \CC \see{\VRef{s:C++RelatedWork}}, for basic types with type inferencing and static initialization (constant expression). 529 Go has @const@ aliasing declarations, similar to \CC \see{\VRef{s:C++RelatedWork}}, for basic types with type inferencing and static initialization (constant expression). 530 The most basic form of constant definition is a @const@ keyword, followed by the name of constant, an optional type declaration of the constant, and a mandatory initialize. 531 For exmaple: 539 532 \begin{Go} 540 533 const R @int@ = 0; const G @uint@ = 1; const B = 2; $\C{// explicit typing and type inferencing}$ … … 544 537 const V = 3.1; const W = 3.1; 545 538 \end{Go} 546 Since these declarations are immutable variables, they are unscoped and Go has no overloading. 547 548 Go provides an enumeration-like feature to group together @const@ declaration into a block and introduces a form of auto-initialization. 539 Since these declarations are immutable variables, they are unscoped and Go has no overloading. If no type declaration provided, Go infers 540 type from the initializer expression. 541 542 % Go provides an enumeration-like feature to group together @const@ declaration into a block and introduces a form of auto-initialization. 543 These named constants can be grouped together in one @const@ declaration block and introduces a form of auto-initialization. 549 544 \begin{Go} 550 545 const ( R = 0; G; B ) $\C{// implicit initialization: 0 0 0}$ 551 546 const ( Fred = "Fred"; Mary = "Mary"; Jane = "Jane" ) $\C{// explicit initialization: Fred Mary Jane}$ 552 const ( S = 0; T; USA = "USA"; U; V = 3.1; W ) $\C{// type change,implicit/explicit: 0 0 USA USA 3.1 3.1}$547 const ( S = 0; T; USA = "USA"; U; V = 3.1; W ) $\C{// implicit/explicit: 0 0 USA USA 3.1 3.1}$ 553 548 \end{Go} 554 549 The first identifier \emph{must} be explicitly initialized; 555 550 subsequent identifiers can be implicitly or explicitly initialized. 556 Implicit initialization is the \emph{previous} (predecessor) identifier value. 557 558 Each @const@ declaration provides an implicit integer counter starting at zero, called \lstinline[language=Go]{iota}. 551 Implicit initialization always uses the \emph{previous} (predecessor) constant expression initializer. 552 553 % Each @const@ declaration provides an implicit integer counter starting at zero, called \lstinline[language=Go]{iota}. 554 Each const declaration is often paired with a const expression \lstinline[language=Go]{iota} to re-define its 555 implicit initialization. \lstinline[language=Go]{iota} represents an sequence of natural number starting from zero. 556 Every implicit or explicit \lstinline[language=Go]{iota} increments the value of the expression by one. 559 557 Using \lstinline[language=Go]{iota} outside of a @const@ block always sets the identifier to zero. 560 558 \begin{Go} 561 559 const R = iota; $\C{// 0}$ 562 560 \end{Go} 563 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. 561 % 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. 562 Inside a @const@ block, if a constant has \lstinline[language=Go]{iota} initializer, its successor will also use \lstinline[language=Go]{iota} initializer. 563 \lstinline[language=Go]{iota} is no different than other constant expression when it is used in implicit initialization, but 564 thanks to the increment natural of \lstinline[language=Go]{iota}, the successor will have a value equal to its predecessor plus 1. 564 565 \begin{Go} 565 566 const ( R = @iota@; G; B ) $\C{// implicit: 0 1 2}$ 567 % const ( C = @iota + B + 1@; G; Y ) $\C{// implicit: 3 4 5}$ 568 \end{Go} 569 The constant blocks from the previous example is equivalanet to: 570 \begin{Go} 571 const ( R = @iota@; G=@iota@; B=@iota@ ) $\C{// implicit: 0 1 2}$ 572 \end{Go} 573 R, G, B have values 0, 1, 2, respectively, because \lstinline[language=Go]{iota} is an increasing. 574 575 Similarly, 576 \begin{Go} 566 577 const ( C = @iota + B + 1@; G; Y ) $\C{// implicit: 3 4 5}$ 567 578 \end{Go} 568 An underscore \lstinline[language=golang]{const} identifier advances \lstinline[language=Go]{iota}. 579 can be rewritten as: 569 580 \begin{Go} 570 const ( O1 = iota + 1; @_@; O3; @_@; O5 ) // 1, 3, 5581 const ( C = @iota + B + 1@; G = @iota + B + 1@; Y = @iota + B + 1@ ) $\C{// implicit: 3 4 5}$ 571 582 \end{Go} 572 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. 583 Go's grouped constants do not define a new type, and constants in the same block can have heterogeneous types. 584 These two characteristics differs a grouped constant from an enumeration, but also gives a direction on approximating enumeration in Go: 585 first to define a new type externally, and make sure all constants in the same group will have the new type. 573 586 \begin{Go} 574 const ( Mon = iota; Tue; Wed; // 0, 1, 2 575 @Thu = 10@; Fri; Sat; @Sun = itoa@ ) $\C{// 10, 10, 10, {\color{red}6}}$ 587 type Language int64 588 const ( 589 C Language = iota 590 CPP 591 CSharp 592 CFA 593 Go 594 ) 576 595 \end{Go} 577 Auto-initialization from \lstinline[language=Go]{iota} is restarted and \lstinline[language=Go]{iota} reinitialized with an expression containing at most \emph{one} \lstinline[language=Go]{iota}. 578 \begin{Go} 579 const ( V1 = iota; V2; @V3 = 7;@ V4 = @iota@ + 1; V5 ) // 0 1 7 4 5 580 const ( Mon = iota; Tue; Wed; // 0, 1, 2 581 @Thu = 10;@ Fri = @iota@ - Wed + Thu - 1; Sat; Sun ) // 10, 11, 12, 13 582 \end{Go} 583 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 initialization expressions containing \lstinline[language=Go]{iota}. 584 Note, because \lstinline[language=Go]{iota} is incremented for an explicitly initialized identifier or @_@, 585 at @Fri@ \lstinline[language=Go]{iota} is 4 requiring the minus one to compute the value for @Fri@. 596 By typing the first constant as @Language@ and assigning initializer with \lstinline[language=Go]{iota}, all other constants will have the same type 597 and the same initialzer. It is a close approximation, but it is not a real enumeration. The definition of the "enumerated type" is separate from 598 the "enumerator definition", and nothing stop outside constants to have the type @Language@. 599 600 % An underscore \lstinline[language=golang]{const} identifier advances \lstinline[language=Go]{iota}. 601 % \begin{Go} 602 % const ( O1 = iota + 1; @_@; O3; @_@; O5 ) // 1, 3, 5 603 % \end{Go} 604 % 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. 605 % \begin{Go} 606 % const ( Mon = iota; Tue; Wed; // 0, 1, 2 607 % @Thu = 10@; Fri; Sat; @Sun = itoa@ ) $\C{// 10, 10, 10, {\color{red}6}}$ 608 % \end{Go} 609 % Auto-initialization from \lstinline[language=Go]{iota} is restarted and \lstinline[language=Go]{iota} reinitialized with an expression containing at most \emph{one} \lstinline[language=Go]{iota}. 610 % \begin{Go} 611 % const ( V1 = iota; V2; @V3 = 7;@ V4 = @iota@ + 1; V5 ) // 0 1 7 4 5 612 % const ( Mon = iota; Tue; Wed; // 0, 1, 2 613 % @Thu = 10;@ Fri = @iota@ - Wed + Thu - 1; Sat; Sun ) // 10, 11, 12, 13 614 % \end{Go} 615 % 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 initialization expressions containing \lstinline[language=Go]{iota}. 616 % Note, because \lstinline[language=Go]{iota} is incremented for an explicitly initialized identifier or @_@, 617 % at @Fri@ \lstinline[language=Go]{iota} is 4 requiring the minus one to compute the value for @Fri@. 618 586 619 587 620 Basic switch and looping are possible. … … 610 643 \end{tabular} 611 644 \end{cquote} 612 However, the loop prints the values from 0 to 13 because there is no actual enumeration.645 However, the loop in this example prints the values from 0 to 13 because there is no actual enumeration. 613 646 614 647 A constant variable can be used as an array dimension or a subscript. … … 627 660 Week day = Week.Sat; 628 661 \end{Java} 629 The enumerator's members are scoped and cannot be made \lstinline[language=java]{public}, hence requiringqualification.662 The enumerator's members are scoped and requires qualification. 630 663 The value of an enumeration instance is restricted to its enumerators. 631 664 … … 663 696 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@. 664 697 The implementation constructor must be private since it is only used internally to initialize the enumerators. 665 Initialization occurs at the enumeration-type declaration for each enumerator in the first line.698 Initialization occurs at the enumeration-type declaration. 666 699 667 700 Enumerations can be used in the @if@ and @switch@ statements but only for equality tests. … … 691 724 692 725 There are no arithmetic operations on enumerations, so there is no arithmetic way to iterate through an enumeration without making the implementation type \lstinline[language=Java]{public}. 693 Like \Csharp, looping over an enumeration is done using method @values@, which returns an array of enumerator values (expensive operation). 726 Like \Csharp, looping over an enumeration is done using static method @values@, which returns an array of enumerator values. 727 Unfortunately, @values@ is an expensive @O(n)@ operation because it creates a new array every time it is called. 694 728 \begin{Java} 695 729 for ( Week d : Week.values() ) { … … 700 734 Like \Csharp, enumerating is supplied indirectly through another enumerable type, not via the enumeration. 701 735 736 % 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. 737 % There is also a specialized version of @HashMap@ with enumerator keys, which has performance benefits. 738 Java provides @EnumSet@, an auxiliary data structure that takes an enum @class@ as parameter (Week.class) for its construction, and it contains members only with the supplied 739 enum type. @EnumSet@ is enumerable because it extends @AbstractSet@ interfaces and thus supports direct enumerating via @forEach@. It also has subset operation 740 @range@ and it is possible to add to and remove from members of the set. 741 @EnumSet@ supports more enumeration features, but it is not an enumeration type: it is a set of enumerators from a pre-define enum. 742 743 702 744 An enumeration type cannot declare an array dimension nor can an enumerator be used as a subscript. 703 745 Enumeration inheritence is disallowed because an enumeration is \lstinline[language=Java]{final}. 704 705 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.706 There is also a specialized version of @HashMap@ with enumerator keys, which has performance benefits.707 708 746 709 747 \section{Rust} … … 733 771 adt = ADT::S(s); println!( "{:?}", adt ); 734 772 @match@ adt { 735 ADT::I( i ) =>println!( "{:}", i ),736 ADT::F( f ) =>println!( "{:}", f ),737 ADT::S( s ) =>println!( "{:} {:}", s.i, s.j ),773 ADT::I( i ) $=>$ println!( "{:}", i ), 774 ADT::F( f ) $=>$ println!( "{:}", f ), 775 ADT::S( s ) $=>$ println!( "{:} {:}", s.i, s.j ), 738 776 } 739 777 \end{rust} … … 757 795 let mut week : Week = Week::Mon; 758 796 match week { 759 Week::Mon =>println!( "Mon" ),797 Week::Mon $=>$ println!( "Mon" ), 760 798 ... 761 Week::Sun =>println!( "Sun" ),799 Week::Sun $=>$ println!( "Sun" ), 762 800 } 763 801 \end{rust} … … 813 851 Week::Mon | Week:: Tue | Week::Wed | Week::Thu 814 852 | Week::Fri => println!( "weekday" ), 815 Week::Sat | Week:: Sun =>println!( "weekend" ),853 Week::Sat | Week:: Sun $=>$ println!( "weekend" ), 816 854 } 817 855 \end{c++} 818 856 \end{tabular} 819 857 \end{cquote} 820 However, there is no mechanism to iterate through an enumeration without casting to integral and positions versus values is not handled. 858 % However, there is no mechanism to iterate through an enumeration without casting to integral and positions versus values is not handled. 859 Like C/\CC, there is no mechanism to iterate through an enumeration. It can only be approximated 860 by a loop over a range of enumerator and will not work if enumerator values is a sequence of natural numbers. 821 861 \begin{c++} 822 862 for d in Week::Mon as isize ..= Week::Sun as isize { … … 825 865 0 1 2 @3 4 5 6 7 8 9@ 10 11 12 13 826 866 \end{c++} 827 An enumeration type cannot declare an array dimension nor as a subscript. 828 There is no mechanism to subset or inherit from an enumeration. 867 % An enumeration type cannot declare an array dimension nor as a subscript. 868 There is no direct way to harmonize an enumeration and another data structure. For example, 869 there is no mapping from an enumerated type to an array type. 870 In terms of extensibility, there is no mechanism to subset or inherit from an enumeration. 829 871 830 872 831 873 \section{Swift} 832 874 \label{s:Swift} 833 875 % https://www.programiz.com/swift/online-compiler 834 835 Like Rust, Swift @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration.876 Despite being named as enumeration, A Swift @enum@ is in fact a ADT: cases (enumerators) of an @enum@ can have heterogeneous types and be recursive. 877 % Like Rust, Swift @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration. 836 878 When @enum@ is an ADT, pattern matching is used to discriminate among the variant types. 837 879 \begin{cquote} … … 875 917 \end{tabular} 876 918 \end{cquote} 877 Note, after an @adt@'s type is know, the enumerator is inferred without qualification, \eg @.I(3)@. 878 879 An enumeration is created when \emph{all} the enumerators are unit-type, which is like a scoped, opaque enumeration. 919 % Note, after an @adt@'s type is know, the enumerator is inferred without qualification, \eg @.I(3)@. 920 Normally an enumeration case needs a type qualification. But in the example when pattern matching @adt@, which 921 has a type @ADT@, the context provides that the cases refer to @ADT@'s cases and no explicit type qualification is required. 922 923 % An enumeration is created when \emph{all} the enumerators are unit-type, which is like a scoped, opaque enumeration. 924 Without type declaration for enumeration cases, a Swift enum syntax defined a unit-type enumeration, which is like a scoped, opaque enumeration. 880 925 \begin{swift} 881 926 enum Week { case Mon, Tue, Wed, Thu, Fri, Sat, Sun }; // unit-type 882 927 var week : Week = @Week.Mon@; 883 928 \end{swift} 884 As well, it is possible to type \emph{all} the enumerators with a common type, and set different values for each enumerator; 885 for integral types, there is auto-incrementing. 929 % As well, it is possible to type \emph{all} the enumerators with a common type, and set different values for each enumerator; 930 % for integral types, there is auto-incrementing. 931 As well, it is possible to type associated values of enumeration cases with a common types. 932 When enumeration cases are typed with a common integral type, Swift auto-initialize enumeration cases following the same initialization scheme as C language. 933 If enumeration is typed with @string@, its cases are auto-initialized to case names (labels). 886 934 \begin{cquote} 887 935 \setlength{\tabcolsep}{15pt} … … 933 981 \end{tabular} 934 982 \end{cquote} 935 Enumerating is accomplished by inheriting from @CaseIterable@ without any associated values. 983 Enumerating is accomplished by inheriting from @CaseIterable@ protocol, which has a static 984 @enum.allCases@ property that returns a collection of all the cases for looping over an enumeration type or variable. 985 Like \CFA, Swift's default enumerator output is the case name (label). An enumerator of a typed enumeration has attribute 986 @rawValue@ that return its case value. 936 987 \begin{swift} 937 988 enum Week: Comparable, @CaseIterable@ { … … 943 994 Mon Tue Wed Thu Fri Sat Sun 944 995 \end{swift} 945 The @enum.allCases@ property returns a collection of all the cases for looping over an enumeration type or variable (expensive operation). 946 947 A typed enumeration is accomplished by inheriting from any Swift type, and accessing the underlying enumerator value is done with the attribute @rawValue@. 948 Type @Int@ has auto-incrementing from the previous enumerator; 949 type @String@ has auto-incrementing of the enumerator label. 996 997 950 998 \begin{cquote} 951 999 \setlength{\tabcolsep}{15pt} … … 975 1023 \end{cquote} 976 1024 977 There is a bidirectional conversion from typed enumerator to @rawValue@ and vice versa.1025 There is a safe bidirectional conversion from typed enumerator to @rawValue@ and vice versa. 978 1026 \begin{swift} 979 var weekInt : WeekInt = WeekInt.Mon;980 1027 if let opt = WeekInt( rawValue: 0 ) { // test optional return value 981 print( weekInt.rawValue, opt ) // 0 Mon1028 print( opt.rawValue, opt ) // 0 Mon 982 1029 } else { 983 1030 print( "invalid weekday lookup" ) 984 1031 } 985 1032 \end{swift} 986 Conversion from @rawValue@ to enumerator may fail (bad lookup), so the result is an optional value. 987 1033 % Conversion from @rawValue@ to enumerator may fail (bad lookup), so the result is an optional value. 1034 In the previous exmaple, the initialization of @opt@ fails when there is no enumeration cases has value equals 0, resulting in a 1035 @nil@ value. Initialization from a raw value is considered a expensive operation because it requires a value lookup. 988 1036 989 1037 \section{Python 3.13} … … 1004 1052 class Week(!Enum!): Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7 1005 1053 \end{python} 1006 and/or explicitly auto-initialized , \eg:1054 and/or explicitly auto-initialized with @auto@ method, \eg: 1007 1055 \begin{python} 1008 1056 class Week(Enum): Mon = 1; Tue = 2; Wed = 3; Thu = 10; Fri = !auto()!; Sat = 4; Sun = !auto()! 1009 1057 Mon : 1 Tue : 2 Wed : 3 Thu : 10 Fri : !11! Sat : 4 Sun : !12! 1010 1058 \end{python} 1011 where @auto@ increments by 1 from the previous @auto@ value \see{Go \lstinline[language=Go]{iota}, \VRef{s:Go}}. 1012 @auto@ is controlled by member @_generate_next_value_()@, which can be overridden: 1059 @auto@ is controlled by member @_generate_next_value_()@, which by default return one plus the highest value among enumerators, and can be overridden: 1013 1060 \begin{python} 1014 1061 @staticmethod … … 1197 1244 % https://dev.realworldocaml.org/runtime-memory-layout.html 1198 1245 1199 Like Haskell, OCaml @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration.1246 Like Swift (\VRef{s:Swift}) and Haskell (\VRef{s:AlgebraicDataType}), OCaml @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration. 1200 1247 When @enum@ is an ADT, pattern matching is used to discriminate among the variant types. 1201 1248 \begin{cquote} … … 1236 1283 \end{tabular} 1237 1284 \end{cquote} 1238 (Note, after an @adtv@'s type is know, the enumerator is inferred without qualification, \eg @I(3)@.) 1285 % (Note, after an @adtv@'s type is know, the enumerator is inferred without qualification, \eg @I(3)@.) 1286 1239 1287 The type names are independent of the type value and mapped to an opaque, ascending, integral tag, starting from 0, supporting relational operators @<@, @<=@, @>@, and @>=@. 1240 1288 \begin{cquote} … … 1278 1326 1279 1327 While OCaml enumerators have an ordering following the definition order, they are not enumerable. 1280 To iterate over all enumerators, an OCaml type needs to derive from the @enumerate@ preprocessor, which appends a list of all enumerators to the program abstract syntax tree (AST). 1281 However, the list of values may not persist in the defined ordering. 1282 As a consequence, there is no meaningful enumerating mechanism. 1283 1284 Enumeration subsetting is allowed but inheritance is restricted to classes not types. 1285 \begin{ocaml} 1286 type weekday = Mon | Tue | Wed | Thu | Fri 1287 type weekend = Sat | Sun 1288 type week = Weekday of weekday | Weekend of weekend 1289 let day : week = Weekend Sun 1290 \end{ocaml} 1328 To iterate over all enumerators, an OCaml type needs to derive from the @enumerate@ PPX (Pre-Preocessor eXtension), which appends a list of all enumerators to the program abstract syntax tree (AST). 1329 However, as stated in the documentation, @enumerate@ PPX does not guarantee the order of the list. 1330 PPX is beyond the scope of OCaml native language and it is a preprocessor directly modifying a parsed AST. In conclusion, there is no enumerating mechanism within the scope of OCaml language. 1291 1331 1292 1332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 1527 1567 opaque & \CM & & & \CM & \CM & & \CM & \CM & & & & \CM \\ 1528 1568 \hline 1529 typed & Int & Int & Int egral & H & U & H & U/H & U/H & H & Int & Integral& U \\1569 typed & Int & Int & Int & H & U & H & U/H & U/H & H & Int & Int & U \\ 1530 1570 \hline 1531 1571 safety & \CM & \CM & & \CM & \CM & & \CM & \CM & & & \CM & \CM \\ … … 1533 1573 posn ordered & Implied & Implied & & \CM & & & & & & & & \CM \\ 1534 1574 \hline 1535 unique values & \CM & \CM & & 1575 unique values & \CM & \CM & &\CM & & & & \CM & & & & \\ 1536 1576 \hline 1537 auto-init & \CM & all or none & \CM & 1577 auto-init & \CM & all or none & \CM & N/A & & \CM & \CM & \CM & \CM & \CM & \CM & \CM \\ 1538 1578 \hline 1539 1579 (Un)Scoped & U & U & S & S & S & U & S & S & S & U & U/S & U/S \\ … … 1545 1585 arr. dim. & \CM & \CM & & & & & & & & & & \CM \\ 1546 1586 \hline 1547 subset & \CM & \CM & & \CM& & & & & & & & \CM \\1587 subset & \CM & \CM & & & & & & & & & & \CM \\ 1548 1588 \hline 1549 1589 superset & & & & & & & & & & & & \CM \\ … … 1559 1599 Position ordered is implied if the enumerator values must be strictly increasingly. 1560 1600 \item unique value: enumerators must have a unique value. 1561 \item auto-init: Values are auto-initializable by language specification, often being "+1" of the predecessor. 1601 \item auto-init: Values are auto-initializable by language specification. \\ 1602 It is not appliable to OCaml because OCaml enumeration has unit type. 1562 1603 \item (Un)Scoped: U $\Rightarrow$ enumerators are projected into the containing scope. 1563 1604 S $\Rightarrow$ enumerators are contained in the enumeration scope and require qualification.
Note: See TracChangeset
for help on using the changeset viewer.