- Timestamp:
- Sep 14, 2024, 5:07:55 PM (3 months ago)
- Branches:
- master
- Children:
- 8c79dc3c
- Parents:
- 3733643
- Location:
- doc/theses/jiada_liang_MMath
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/CFAenum.tex
r3733643 rdcfcf368 71 71 char * s = label( O_TRUNC ); $\C{// "O\_TRUNC"}$ 72 72 int open = posn( O_WRONLY ); $\C{// 1}$ 73 s = label( mode ); $\C{// "O\_RDONLY"}$ 74 int open = posn( mode ); $\C{// 0}$ 73 75 \end{cfa} 74 76 Equality and relational operations are available. … … 131 133 calling constructors happens at runtime (dynamic). 132 134 135 133 136 \section{Implementation} 134 \CFA-cc is is a transpiler that translates \CFA code into C, which can later be compiled by a C compiler. 135 136 During t he transpilation, \CFA-cc breaks a \CFA enumeration definition into a definition of a C enumeration with the same name and auxiliary arrays: a label array and avalue array for a typed enumeration.137 138 \CFA-cc is is a transpiler translating \CFA code into C, which is compiled by a C compiler. 139 During transpilation, \CFA-cc breaks a \CFA enumeration definition into a definition of a C enumeration with the same name and auxiliary arrays: a label and value array for a typed enumeration. 137 140 For example: 138 141 \begin{cfa} 139 // CFA (source): 140 enum(T) E { E1=t1, E2=t2, E3=t3 }; 142 enum( T ) E { E1 = t1, E2 = t2, E3 = t3 }; 141 143 \end{cfa} 142 144 is compiled into: 143 145 \begin{cfa} 144 // C (transpiled by cfa-cc):145 146 enum E { E1, E2, E3 }; 146 const char * E_labels[3] = { "E1", "E2", "E3" }; 147 const T E_values [3] = { t1, t2, t3 }; 148 \end{cfa} 149 The generated C enumeration will have enumerator values resemble \CFA enumerator positions thanks to C's auto-initialization scheme. 150 A \CFA enumeration variable definition is same in \CFA and C, before or after the transpilation. 151 For example: 147 static const char * E_labels[3] = { "E1", "E2", "E3" }; 148 static const T E_values[3] = { t1, t2, t3 }; 149 \end{cfa} 150 The generated C enumeration has enumerator values that match \CFA enumerator positions because of C's auto-initialization. 151 A \CFA enumeration variable definition is the same in \CFA as C, \eg: 152 152 \begin{cfa} 153 153 enum E e = E1; 154 e; 155 \end{cfa} 156 These two expressions will not change by \CFA-cc. A \CFA enumeration variable will always have the same underlying representation as its generated 157 C enumeration. This implies \CFA enumeration variable does not take up extra memory and \CFA enumeration use @posn@ as its underlying representation. 158 159 Notice that value and label arrays are dynamically allocated data structures that take up 160 memory. If an enumeration is globally defined, the arrays are allocated in the @.data@ section and will be initialized before the program execution. 161 Otherwise, if an enumeration has its definition in a local scope, these arrays will be allocated on the stack and be initialized when the program counter 162 reaches the code location of the enumeration definition. 163 164 % This bring a considerable overhead to the program, in terms of both execution time and storage. 165 % An opaque enumeration has no overhead 166 % for values, and it has been suggested as a future work to leave as an option to not generate the label array. 167 168 Alongs with the enumeration defintion, \CFA-cc adds defintions of attribute functions: @posn@, @label@ and @value@: 154 e = E2; 155 \end{cfa} 156 so these expressions remain unchanged by \CFA-cc. 157 Therefore, a \CFA enumeration variable has the same underlying representation as its generated C enumeration. 158 This semantics implies a \CFA enumeration variable does not use memory, that @posn@ can use its underlying representation, and the label and value arrays take little storage. 159 It should be possible to eliminated the two arrays if unused, either by \CFA if local to a translation unit and unused, or by the linker if global but unreferenced. 160 Also, the label and value arrays are declared @static@ and initialized with constants, so the arrays are allocated in the @.data@ section and initialized before program execution. 161 Hence, there is no addition execution cost unless new enumeration features are use, and storage usage is minimal as the number of enumerations in a program is small as is the number of enumerators in an enumeration. 162 163 Along with the enumeration definition, \CFA-cc generates definitions of the attribute functions, @posn@, @label@ and @value@, for each enumeration: 169 164 \begin{cfa} 170 165 inline int posn( E e ) { return (int) e; } … … 172 167 inline const * E_value( E e ) { return E_values[ (int) e ]; } 173 168 \end{cfa} 174 These functions are not implemented in \CFA code: they are Abstract Syntax Tree (AST) nodes appends to the Abstract Syntax Tree (AST). 175 Notably, the AST subnode for the "cast to @int@" expression inside the functions is annotated as reinterpreted casts. 176 In order words, the effect of a case is only to change the type of an expression, and it stops further reduction on the expression \see{\VRef{s:ValueConversion}}. 177 178 Consequently, \CFA enumeration comes with space and runtime overhead, both for enumeration definition and function call to attribute functions. \CFA made efforts to reduce the runtime 179 overhead on function calls by aggressively reducing @label()@ and @value()@ function calls on an enumeration constant to a constant expression. The interpreted casts are extraneous 180 after type checking and removed in later steps. A @label()@ and @value()@ call on an enumeration variable is a lookup of an element of an array of constant values, and it is up to the 181 C compiler to optimize its runtime. While OpaqueEnum is effectively an "opt-out" of the value overhead, it has been suggested that an option to "opt-out" from labels be added as well. 182 A @label()@ function definition is still necessary to accomplish enumeration traits. But it will return an empty string for an enumeration label when "opt-out" or the enumerator name 183 when it is called on an enumeration constant. It will allow a user not to pay the overhead for labels when the enumerator names of a particular enumerated type are not helpful. 169 where the function calls are normally inlined by the backend C compiler into a few instructions. 170 These functions simplify the job of getting the enumerations types through the type system in the same way as normal functions and calls. 171 Note, the cast to @int@ is actually an internal reinterpreted cast added before type resolution to stop further reduction on the expression by the type resolver \see{\VRef{s:ValueConversion}} and removed in code generation. 172 Finally, to further mitigate \CFA enumeration costs, calls to @label@ and @value@ with an enumeration constant are unrolled into the appropriate constant expression, although this could be left to the backend C compiler. 173 Hence, in space and time costs, \CFA enumerations follow the C philosophy of only paying for what is used, modulo some future work to convince the linker to remove unaccessed @label@ and @value@ arrays, possibly with @weak@ attributes. 174 184 175 185 176 \section{Value Conversion} … … 214 205 % \begin{cfa} 215 206 % forall(T | @CfaEnum(T)@) void bar(T); 216 % 207 % 217 208 % bar(a); $\C{// (3), with cost (0, 0, 1, 0, 0, 0, 0, 0)}$ 218 209 % \end{cfa} … … 236 227 \end{cfa} 237 228 238 The restriction on C's enumeration initializers being constant expression is relaxed on \CFA enumeration. 239 Therefore, an enumerator initializer allows function calls like @?+?( S & s, one_t )@ and @?{}( S & s, zero_t )@. 240 It is because the values of \CFA enumerators are not stored in the compiled enumeration body but in the @value@ array, which 229 The restriction on C's enumeration initializers being constant expression is relaxed on \CFA enumeration. 230 Therefore, an enumerator initializer allows function calls like @?+?( S & s, one_t )@ and @?{}( S & s, zero_t )@. 231 It is because the values of \CFA enumerators are not stored in the compiled enumeration body but in the @value@ array, which 241 232 allows dynamic initialization. 242 233 … … 249 240 \end{cfa} 250 241 Enumeration @Greek@ may have more or less enumerators than @Letter@, but its enumerator values \emph{must} be from @Letter@. 251 Therefore, the set of @Greek@ enumerator values in a subset of the @Letter@ enumerator values. 242 Therefore, the set of @Greek@ enumerator values in a subset of the @Letter@ enumerator values. 252 243 @Letter@ is type compatible with enumeration @Letter@ because value conversions are inserted whenever @Letter@ is used in place of @Greek@. 253 244 \begin{cfa} … … 291 282 However, the position of the underlying representation is the order of the enumerator in the new enumeration. 292 283 \begin{cfa} 293 enum() E1 { B }; $\C{// B}$ 284 enum() E1 { B }; $\C{// B}$ 294 285 enum() E2 { C, D }; $\C{// C D}$ 295 286 enum() E3 { inline E1, inline E2, E }; $\C{// {\color{red}[\(_{E1}\)} B {\color{red}]} {\color{red}[\(_{E2}\)} C D {\color{red}]} E}$ … … 298 289 In the example, @B@ is at position 0 in @E1@ and @E3@, but position 1 in @E4@ as @A@ takes position 0 in @E4@. 299 290 @C@ is at position 0 in @E2@, 1 in @E3@, and 2 in @E4@. 300 @D@ is at position 1 in @E2@, 2 in @E3@, and 3 in @E4@. 301 302 A subtype enumeration can be casted, or implicitly converted into its supertype, with a @safe@ cost, called \newterm{enumeration conversion}. 291 @D@ is at position 1 in @E2@, 2 in @E3@, and 3 in @E4@. 292 293 A subtype enumeration can be casted, or implicitly converted into its supertype, with a @safe@ cost, called \newterm{enumeration conversion}. 303 294 \begin{cfa} 304 295 enum E2 e2 = C; -
doc/theses/jiada_liang_MMath/Cenum.tex
r3733643 rdcfcf368 22 22 \VRef[Figure]{f:EnumeratorVisibility} shows how resolution, qualification, and casting are used to disambiguate situations for enumerations @E1@ and @E2@. 23 23 24 Aside, name shadowing in \CFA only happens when a name has been redefined with the exact same type. Because an enumeration define its type and enumerators in one definition,25 and enumeration cannot be changed afterward, shadowing an enumerator is not possible (it is impossible to have another @First@ with same type @E1@.).26 27 24 \begin{figure} 28 25 \begin{cfa} … … 43 40 \label{f:EnumeratorVisibility} 44 41 \end{figure} 42 43 Aside, name shadowing in \CFA only happens when a name has been redefined with the \emph{exact} same type. 44 Because an enumeration define its type and enumerators in one definition, shadowing an enumerator is not possible, \ie it is impossible to have another @First@ with same type @E1@. 45 45 46 46 … … 68 68 \end{cfa} 69 69 As in Section~\ref{s:CVisibility}, opening multiple scoped enumerations in a @with@ can result in duplicate enumeration names, but \CFA implicit type resolution and explicit qualification/casting handle this localized scenario. 70 70 71 71 72 \section{Type Safety} -
doc/theses/jiada_liang_MMath/background.tex
r3733643 rdcfcf368 15 15 \item 16 16 For @#define@, the programmer must explicitly manage the constant name and value. 17 Furthermore, these C preprocessor macro names are outside the C type system and can unintentionally change semantics of a program.17 Furthermore, these C preprocessor macro names are outside the C type system and can unintentionally change program text. 18 18 \item 19 19 The same explicit management is true for the @const@ declaration, and the @const@ variable cannot appear in constant-expression locations, like @case@ labels, array dimensions,\footnote{ … … 136 136 A ``plain'' @int@ object has the natural size suggested by the architecture of the execution environment (large enough to contain any value in the range @INT_MIN@ to @INT_MAX@ as defined in the header @<limits.h>@).~\cite[\S~6.2.5(5)]{C11} 137 137 \end{quote} 138 However, @int@ means 4 bytes on both 32/64-bit architectures, which does not seem like the ``natural'' size for a 64-bit architecture. 139 % Whereas @long int@ means 4 bytes on a 32-bit and 8 bytes on 64-bit architectures, and @long long int@ means 8 bytes on both 32/64-bit architectures, where 64-bit operations are simulated on 32-bit architectures. 138 \VRef[Table]{t:IntegerStorageSizes} shows integer storage sizes. 139 On UNIX systems (LP64), @int@ means 4 bytes on both 32/64-bit architectures, which does not seem like the ``natural'' size for a 64-bit architecture. 140 Whereas @long int@ means 4 bytes on a 32-bit and 8 bytes on 64-bit architectures, and @long long int@ means 8 bytes on both 32/64-bit architectures, where 64-bit operations are simulated on 32-bit architectures. 141 On Windows systems (LLP64), @int@ and @long@ mean 4 bytes on both 32/64-bit architectures, which also does not seem like the ``natural'' size for a 64-bit architecture. 140 142 \VRef[Figure]{f:gccEnumerationStorageSize} shows both @gcc@ and @clang@ partially ignore this specification and type the integral size of an enumerator based on its initialization. 141 143 Hence, initialization in the range @INT_MIN@..@INT_MAX@ results in a 4-byte enumerator, and outside this range, the enumerator is 8 bytes. 142 144 Note that @sizeof( typeof( IMin ) ) != sizeof( E )@, making the size of an enumerator different than its containing enumeration type, which seems inconsistent. 145 146 \begin{table} 147 \centering 148 \caption{Integer Storage Sizes (bytes)} 149 \label{t:IntegerStorageSizes} 150 \begin{tabular}{@{}rcc@{}} 151 Type & LP64 & LLP64 \\ 152 @char@ & 1 & 1 \\ 153 @short@ @int@ & 2 & 2 \\ 154 @int@ & 4 & 4 \\ 155 @long@ @int@ & 8 & 4 \\ 156 @long@ @long@ @int@ & 8 & 8 \\ 157 pointer & 8 & 8 158 \end{tabular} 159 \end{table} 143 160 144 161 \begin{figure} … … 483 500 More type assertions mean more constraints on argument types, making the function less generic. 484 501 485 \CFA defines two special cost values: @zero@and @infinite@.486 A conversion cost is @zero@when the argument and parameter have an exact match, and a conversion cost is @infinite@ when there is no defined conversion between the two types.502 \CFA defines two special cost values: 0 and @infinite@. 503 A conversion cost is 0 when the argument and parameter have an exact match, and a conversion cost is @infinite@ when there is no defined conversion between the two types. 487 504 For example, the conversion cost from @int@ to a @struct S@ is @infinite@. 488 505 -
doc/theses/jiada_liang_MMath/intro.tex
r3733643 rdcfcf368 39 39 For example, the week, the weekdays, the weekend, and every second day of the week. 40 40 \begin{cfa}[morekeywords={in}] 41 for ( cursor in Mon, Tue, Wed, Thu, Fri, Sat, Sun }... $\C[3.75in]{// week}$42 for ( cursor in Mon, Tue, Wed, Thu, Fri }... $\C{// weekday}$43 for ( cursor in Sat, Sun }... $\C{// weekend}$44 for ( cursor in Mon, Wed, Fri, Sun }... $\C{// every second day of week}\CRT$41 for ( cursor in Mon, Tue, Wed, Thu, Fri, Sat, Sun ) ... $\C[3.75in]{// week}$ 42 for ( cursor in Mon, Tue, Wed, Thu, Fri ) ... $\C{// weekday}$ 43 for ( cursor in Sat, Sun ) ... $\C{// weekend}$ 44 for ( cursor in Mon, Wed, Fri, Sun ) ... $\C{// every second day of week}\CRT$ 45 45 \end{cfa} 46 46 A set can have a partial or total ordering, making it possible to compare set elements, \eg Monday is before Tuesday and Tuesday is after. … … 73 73 74 74 The term \newterm{enumeration} defines a type with a set of new constants, and the term \newterm{enumerator} represents an arbitrary alias name \see{\VRef{s:CEnumeration} for the name derivations}. 75 An enumerated type can have th ree fundamental properties,\newterm{label} (name), \newterm{order} (position), and \newterm{value} (payload).75 An enumerated type can have the following properties: \newterm{label} (name), \newterm{order} (position), and \newterm{value} (payload). 76 76 \begin{cquote} 77 77 \sf\setlength{\tabcolsep}{3pt} … … 234 234 % The association between ADT and enumeration occurs if all the constructors have a unit (empty) type, \eg @struct unit {}@. 235 235 % Note, the unit type is not the same as \lstinline{void}. 236 In terms of functional programming linguistics, enumerations often refers to a @unit type@ ADT, where @unit type@ is a type 237 that carry no information. The unit type is different than @void@ in C, because @void@ is type has no value, i.e., it is a empty set. 238 In constract, unit type has exactly one value, often called a @nil@ value. 239 Because of this distinction, it is not possbile to have a variable to have type @void@ or to be assigned with a value @void@. 240 In practice, @void@ in C is more like an annotation that nothing is expected in this place. A function takes @void@ as parameter 241 is essentially a function that expects no parameter. A function that return @void@ cannot be used as a parameter of a function that expects no 242 parameter. Therefore, the following code is illegal in C: 236 In terms of functional programming linguistics, enumerations often refer to a @unit type@ ADT, which is a set with the @nil@ value carrying no information. 237 The unit type is different from type @void@ in C, because @void@ has no value, which is an empty set. 238 Hence, @void@ is a C annotation that nothing is expected in this place. 239 For example, a function that takes a @void@ parameter and returns a @void@ is a function that expects no parameters and returns nothing. 240 \begin{cfa} 241 void foo( void ); 242 foo(); $\C{// no arguments and no result}$ 243 \end{cfa} 244 Because of this distinction, it is impossible to have a variable of type @void@, to assign a @void@ value, or have a function taking and returning multiple @void@s. 245 \begin{cfa} 246 void v; $\C{// disallowed}$ 247 v = void; 248 [ void, void ] bar( void, void ); 249 \end{cfa} 250 Programming languages often use an empty parameter list to imply no value and no return type for empty return. 251 \begin{cfa} 252 [] bar(); $\C{// \CFA empty/empty prototype}$ 253 \end{cfa} 254 However, C is saddled with an empty parameter list meaning a list of unknown type parameters, \ie @var_arg@, which is changed to @void@ in \CC/\CFA. 255 As a result, a function that returns @void@ cannot be used as a parameter of a function that expects no parameter. 243 256 \begin{cfa} 244 257 void foo( void ); … … 246 259 \end{cfa} 247 260 248 This is a more notably issue when to use @variant@ to simulate @ADT@: @void@ cannot be used as an empty variant. To solve this problem, 249 \CC introduced @monstate@, a type that can be instantiated as a value, but holds no information. There is no standard representation of 250 @unit@ in C, and it is often approximated by a user-defined type that has no field, for example: 251 \begin{cfa} 252 struct Empty {} e; $\C{// empty type}$ 253 Empty bar( Empty ); 254 bar(@bar(e)@); 255 \end{cfa} 256 @Empty@ is a close approximation to @unit@ if and only if @Empty@ is the only representation of @unit@ in the program. If a program has 257 a second type, say @Nothing@, that also tries to resemble @unit@, then @unit@ concepts falls apart. 261 This issue arose when simulating an ADT using a \CC @variant@: @void@ cannot be used as an empty variant. 262 To solve this problem, \CC introduced @std::monstate@~\cite{C++monstate}, a type that can be instantiated as a value but holds no information. 263 A similar approximation in C is to define a @struct@ type with no fields. 264 \begin{cfa} 265 struct Unit {} e; $\C{// empty type}$ 266 Unit bar( Unit ); 267 bar( @bar( e )@ ); 268 \end{cfa} 269 Because @std::monostate@ and @Unit@ are user-defined types versus part of the type system, they are only an approximation to @unit@ because other @unit@ types can be defined. 258 270 259 271 In the Haskell ADT: -
doc/theses/jiada_liang_MMath/relatedwork.tex
r3733643 rdcfcf368 336 336 \end{c++} 337 337 whereas C @const@ declarations without @static@ are marked @R@. 338 This difference results from linking concerns that come from templates. 338 339 339 340 The following \CC non-backward compatible change is made, plus the safe-assignment change shown in~\VRef{s:TypeSafety}. … … 417 418 A common workaround is to iterate over enumerator as integral values, but it only works if 418 419 enumerators resemble a sequence of natural, i.e., enumerators are auto-initialized. 419 Otherwise s, the iteration would have integers that are not enumeration values.420 Otherwise, the iteration would have integers that are not enumeration values. 420 421 \begin{c++} 421 422 enum Week { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun }; … … 497 498 To indirectly enumerate, \Csharp's Enum library provides @Enum.GetValues@, 498 499 % 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. 500 a static member of abstract Enum type that return a reference to an array of all enumeration constants. 501 Internally, a Enum type has a static member called @fieldInfoHash@ -- a @Hashtable@ that stores enumerators information. 502 The field is populated on-demand: it only contains information if a @reflection@ like @GetValues@ is called. 503 As an optimization, this information is cached, so the cost of reflection is paid once throughout the lifetime of a program. 504 @GetValues@ then converts a @Hashtable@ to an @Array@, which supports enumerating. 503 505 \begin{csharp} 504 506 foreach ( Week d in @Enum.GetValues@( typeof(Week) ) ) { … … 507 509 Mon 0, Tue 1, Wed 2, Thu 10, Fri 11, Sat 12, Sun 13, 508 510 \end{csharp} 509 Hence, enumerating is not supplied directly by the enumeration, but indirectly through the e numerable array type.511 Hence, enumerating is not supplied directly by the enumeration, but indirectly through the expensive $O(N)$ creation of an enumerable array type, and recreating this array for each enumerating, versus direct arithmetic. 510 512 511 513 An enumeration type cannot declare an array dimension but an enumerator can be used as a subscript. … … 529 531 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 532 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 ex maple:533 For example: 532 534 \begin{Go} 533 535 const R @int@ = 0; const G @uint@ = 1; const B = 2; $\C{// explicit typing and type inferencing}$ … … 541 543 542 544 % 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 introducesa form of auto-initialization.545 These named constants can be grouped together in one @const@ declaration block to introduce a form of auto-initialization. 544 546 \begin{Go} 545 547 const ( R = 0; G; B ) $\C{// implicit initialization: 0 0 0}$ … … 550 552 subsequent identifiers can be implicitly or explicitly initialized. 551 553 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. 557 Using \lstinline[language=Go]{iota} outside of a @const@ block always sets the identifier to zero. 554 A constant block can still use explicit declarations, and following constants inherit that type. 558 555 \begin{Go} 559 const R = iota; $\C{// 0}$ 556 type BigInt int64 557 const ( R @BigInt@ = 0; G; B ) 558 const ( Fred @string@ = "Fred"; Mary = "Mary"; Jane = "Jane" ) 559 const ( S @int@ = 0; T; USA @string@ = "USA"; U; V @float32@ = 3.1; W ) 560 560 \end{Go} 561 Typing the first constant and implicit initializing is still not a enumeration because there is no unique type for the constant block; 562 nothing stops other constant blocks from having the same type. 563 564 Each @const@ declaration provides an implicit \emph{compile-time} integer counter starting at @0@, called \lstinline[language=Go]{iota}, which is post-incremented after each constant declaration. 565 % Each @const@ declaration is often paired with a const expression \lstinline[language=Go]{iota} to re-define its implicit initialization. 566 % \lstinline[language=Go]{iota} represents a sequence of natural numbers starting from zero. 567 % Using \lstinline[language=Go]{iota} outside of a @const@ block always sets the identifier to zero. 568 % \begin{Go} 569 % const R = iota; $\C{// 0}$ 570 % \end{Go} 561 571 % 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.572 % Inside a @const@ block, if a constant has \lstinline[language=Go]{iota} initializer, its successor will also use \lstinline[language=Go]{iota} initializer. 573 % Inside a @const@ block, if a constant has \lstinline[language=Go]{iota} initializer, its successor will also use \lstinline[language=Go]{iota} initializer. 574 % \lstinline[language=Go]{iota} is no different than other constant expression when it is used in implicit initialization, but thanks to the increment natural of \lstinline[language=Go]{iota}, the successor will have a value equal to its predecessor plus 1. 565 575 \begin{Go} 566 const ( R = @iota@; G; B ) $\C{// implicit: 0 1 2}$567 % const ( C = @iota + B + 1@; G; Y )$\C{// implicit: 3 4 5}$576 const ( R = @iota@; G; B ) $\C{// implicit: 0 1 2}$ 577 const ( C = @iota + B + 1@; G; Y ) $\C{// implicit: 3 4 5}$ 568 578 \end{Go} 569 The constant blocks from the previous example is equivalanet to:579 which are equivalent to: 570 580 \begin{Go} 571 const ( R = @iota@; G=@iota@; B=@iota@ ) $\C{// implicit: 0 1 2}$ 581 const ( R = @iota@; G = @iota@; B = @iota@ ) $\C{// implicit: 0 1 2}$ 582 const ( C = @iota + B + 1@; G = @iota + B + 1@; Y = @iota + B + 1@ ) $\C{// implicit: 3 4 5}$ 572 583 \end{Go} 573 R, G, B have values 0, 1, 2, respectively, because \lstinline[language=Go]{iota} is an increasing. 574 575 Similarly, 584 An underscore \lstinline[language=golang]{const} identifier advances \lstinline[language=Go]{iota}. 576 585 \begin{Go} 577 const ( C = @iota + B + 1@; G; Y ) $\C{// implicit: 3 45}$586 const ( O1 = iota + 1; @_@; O3; @_@; O5 ) $\C{// 1, 3, 5}$ 578 587 \end{Go} 579 can be rewritten as: 588 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. 580 589 \begin{Go} 581 const ( C = @iota + B + 1@; G = @iota + B + 1@; Y = @iota + B + 1@ ) $\C{// implicit: 3 4 5}$ 590 const ( Mon = iota; Tue; Wed; $\C{// 0, 1, 2}$ 591 @Thu = 10@; Fri; Sat; @Sun = iota@ ) $\C{// 10, 10, 10, {\color{red}6}}$ 582 592 \end{Go} 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. 593 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}. 586 594 \begin{Go} 587 type Language int64 588 const ( 589 C Language = iota 590 CPP 591 CSharp 592 CFA 593 Go 594 ) 595 const ( V1 = iota; V2; @V3 = 7;@ V4 = @iota@ + 1; V5 ) // 0 1 7 4 5 596 const ( Mon = iota; Tue; Wed; // 0, 1, 2 597 @Thu = 10;@ Fri = @iota@ - Wed + Thu - 1; Sat; Sun ) // 10, 11, 12, 13 595 598 \end{Go} 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 599 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}. 600 Note, because \lstinline[language=Go]{iota} is incremented for an explicitly initialized identifier or @_@, 601 at @Fri@ \lstinline[language=Go]{iota} is 4 requiring the minus one to compute the value for @Fri@. 619 602 620 603 Basic switch and looping are possible. … … 660 643 Week day = Week.Sat; 661 644 \end{Java} 662 The enumerator's members are scoped and requiresqualification.645 The enumerator's members are scoped requiring qualification. 663 646 The value of an enumeration instance is restricted to its enumerators. 664 647 … … 724 707 725 708 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}. 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. 709 Like \Csharp, enumerating is supplied indirectly through another enumerable type, not via the enumeration. 710 Specifically, Java supplies a static method @values@, which returns an array of enumerator values. 711 Unfortunately, @values@ is an expensive @O(n)@ operation, which is recreated each time it is called. 728 712 \begin{Java} 729 713 for ( Week d : Week.values() ) { … … 732 716 0 1 Mon, 1 2 Tue, 2 3 Wed, 3 4 Thu, 4 5 Fri, 5 6 Sat, 6 7 Sun, 733 717 \end{Java} 734 Like \Csharp, enumerating is supplied indirectly through another enumerable type, not via the enumeration.735 718 736 719 % 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 720 % 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.721 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 enum type. 722 @EnumSet@ is enumerable because it extends @AbstractSet@ interfaces and thus supports direct enumerating via @forEach@. 723 It also has subset operation @range@ and it is possible to add to and remove from members of the set. 741 724 @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 725 744 726 An enumeration type cannot declare an array dimension nor can an enumerator be used as a subscript. 745 727 Enumeration inheritence is disallowed because an enumeration is \lstinline[language=Java]{final}. 728 746 729 747 730 \section{Rust} … … 857 840 \end{cquote} 858 841 % 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 approximated860 by a loop over a range of enumerator and will not work if enumerator values isa sequence of natural numbers.842 Like C/\CC, there is no mechanism to iterate through an enumeration. 843 It can only be approximated by a loop over a range of enumerator and only works if the enumerator values are a sequence of natural numbers. 861 844 \begin{c++} 862 845 for d in Week::Mon as isize ..= Week::Sun as isize { … … 866 849 \end{c++} 867 850 % 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.851 There is no direct way to harmonize an enumeration and another data structure. 852 For example, there is no mapping from an enumerated type to an array type. 870 853 In terms of extensibility, there is no mechanism to subset or inherit from an enumeration. 871 854 … … 874 857 \label{s:Swift} 875 858 % https://www.programiz.com/swift/online-compiler 876 Despite being named as enumeration, ASwift @enum@ is in fact a ADT: cases (enumerators) of an @enum@ can have heterogeneous types and be recursive.859 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 860 % Like Rust, Swift @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration. 878 861 When @enum@ is an ADT, pattern matching is used to discriminate among the variant types. … … 917 900 \end{tabular} 918 901 \end{cquote} 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 andno explicit type qualification is required.902 Note, after an @adt@'s type is known, the enumerator is inferred without qualification, \eg @.I(3)@. 903 % Normally an enumeration case needs a type qualification. 904 %However, when pattern matching @adt@ of type @ADT@, the @case@ context provides the type @ADT@ so no explicit type qualification is required. 922 905 923 906 % 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.907 Without type declaration for enumeration cases, the enumerators have unit-type, which is like a scoped, opaque enumeration. 925 908 \begin{swift} 926 909 enum Week { case Mon, Tue, Wed, Thu, Fri, Sat, Sun }; // unit-type … … 929 912 % As well, it is possible to type \emph{all} the enumerators with a common type, and set different values for each enumerator; 930 913 % for integral types, there is auto-incrementing. 931 As well, it is possible to type associated values of enumeration cases with a common type s.914 As well, it is possible to type associated values of enumeration cases with a common type. 932 915 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).916 If an enumeration is typed with @string@, its cases are auto-initialized to case names (labels). 934 917 \begin{cquote} 935 918 \setlength{\tabcolsep}{15pt} … … 981 964 \end{tabular} 982 965 \end{cquote} 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. 966 Enumerating is accomplished by inheriting from @CaseIterable@ protocol, which has a static @enum.@ @allCases@ property that returns a collection of all the cases for looping over an enumeration type or variable. 985 967 Like \CFA, Swift's default enumerator output is the case name (label). An enumerator of a typed enumeration has attribute 986 968 @rawValue@ that return its case value. … … 1032 1014 \end{swift} 1033 1015 % 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. 1016 In the previous example, the initialization of @opt@ fails if there is no enumeration value equal to 0, resulting in a @nil@ value. 1017 Initialization from a raw value is considered a expensive operation because it requires a value lookup. 1018 1036 1019 1037 1020 \section{Python 3.13} … … 1329 1312 However, as stated in the documentation, @enumerate@ PPX does not guarantee the order of the list. 1330 1313 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. 1314 1315 \PAB{Why was this removed?} 1316 Enumeration subsetting is allowed but inheritance is restricted to classes not types. 1317 \begin{ocaml} 1318 type weekday = Mon | Tue | Wed | Thu | Fri 1319 type weekend = Sat | Sun 1320 type week = Weekday of weekday | Weekend of weekend 1321 let day : week = Weekend Sun 1322 \end{ocaml} 1331 1323 1332 1324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -
doc/theses/jiada_liang_MMath/test.go
r3733643 rdcfcf368 20 20 21 21 22 const ( R = 0; G = 3; B = 3; TT = 3 ) // implicit: 0 3 323 const ( Fred = "Fred"; Mary = "Mary"; Jane = "Jane" ) // Fred Mary Jane22 const ( R int = 0; G = 3; B = 3; TT = 3 ) // implicit: 0 3 3 23 const ( Fred string = "Fred"; Mary = "Mary"; Jane = "Jane" ) // Fred Mary Jane 24 24 const ( H = 0; Jack = "Jack"; J; K = 0; I ) // type change, implicit: 0 Jack Jack 25 25 const ( C = iota + G; M = iota; Y ) … … 31 31 const ( D = 1.5; E ); 32 32 33 33 const ( AA int = 3; KK; BB float32 = 3.5; CC = 3.9 ); 34 type BigInt int64 34 35 35 36 func main() { 36 37 fmt.Println( "Go:") 37 38 if 3 == R {}; 39 fmt.Println( AA, KK, BB, CC ) 38 40 fmt.Println( R, G, B ) 39 41 fmt.Println( Fred, Mary, Jane ) -
doc/theses/jiada_liang_MMath/trait.tex
r3733643 rdcfcf368 120 120 Hence, the \CFA enumeration traits never connected with the specific @enum@ kind. 121 121 Instead, anything that can look like the @enum@ kind is considered an enumeration (static structural typing). 122 However, Scala, Go, and Rust traits are nominative: a type explicitly declares a named trait sto be of its type, while in \CFA, any type implementing all requirements declared in a trait implicitly satisfy its restrictions.122 However, Scala, Go, and Rust traits are nominative: a type explicitly declares a named trait to be of its type, while in \CFA, any type implementing all requirements declared in a trait implicitly satisfy its restrictions. 123 123 124 124 One of the key differences between concepts and traits, which is leveraged heavily by \CFA, is the ability to apply new \CFA features to C legacy code. -
doc/theses/jiada_liang_MMath/uw-ethesis.bib
r3733643 rdcfcf368 12 12 year = 2023, 13 13 } 14 15 @misc{C++monstate, 16 keywords = {unit type}, 17 key = {monstate}, 18 title = {{\sf std::monostate3}}, 19 author = {cppreference.com}, 20 howpublished= {\url{https://en.cppreference.com/w/cpp/utility/variant/monostate}}, 21 month = sep, 22 year = 2024, 23 } 24
Note: See TracChangeset
for help on using the changeset viewer.