Changes in / [02c80cdc:4e08a54]
- Files:
-
- 15 edited
-
doc/LaTeXmacros/common.sty (modified) (5 diffs)
-
doc/LaTeXmacros/common.tex (modified) (5 diffs)
-
doc/LaTeXmacros/lstlang.sty (modified) (2 diffs)
-
doc/bibliography/pl.bib (modified) (1 diff)
-
doc/theses/jiada_liang_MMath/CFAenum.tex (modified) (1 diff)
-
doc/theses/jiada_liang_MMath/Makefile (modified) (1 diff)
-
doc/theses/jiada_liang_MMath/background.tex (modified) (1 diff)
-
doc/theses/jiada_liang_MMath/intro.tex (modified) (6 diffs)
-
doc/theses/jiada_liang_MMath/relatedwork.tex (modified) (28 diffs)
-
doc/theses/jiada_liang_MMath/uw-ethesis.bib (modified) (1 diff)
-
doc/uC++toCFA/Makefile (modified) (1 diff)
-
doc/uC++toCFA/uC++toCFA.tex (modified) (14 diffs)
-
doc/user/Makefile (modified) (2 diffs)
-
doc/user/user.tex (modified) (17 diffs)
-
libcfa/src/concurrency/actor.hfa (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.sty
r02c80cdc r4e08a54 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Feb 25 23:30:09202414 %% Update Count : 6 4513 %% Last Modified On : Thu Apr 18 09:14:02 2024 14 %% Update Count : 657 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 108 108 \renewcommand\subparagraph{\@startsection{subparagraph}{4}{\z@}{-1.5ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries\itshape}} 109 109 110 % index macros111 110 \newcommand{\italic}[1]{\emph{\hyperpage{#1}}} 112 111 \newcommand{\Definition}[1]{\textbf{\hyperpage{#1}}} 113 \newcommand{\see}[1]{(see #1)} 112 \newcommand{\see}{\protect\@ifstar\@ssee\@see} 113 \newcommand{\@ssee}[1]{(See #1)} 114 \newcommand{\@see}[1]{(see #1)} 115 116 % index macros 114 117 115 118 % Define some commands that produce formatted index entries suitable for cross-references. … … 152 155 \newcommand{\newtermFontInline}{\emph} 153 156 \newcommand{\newterm}{\protect\@ifstar\@snewterm\@newterm} 157 \newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 154 158 \newcommand{\@newterm}[2][\@empty]{\lowercase{\def\temp{#2}}{\newtermFontInline{#2}}\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 155 \newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi}156 159 157 160 % \snake{<identifier>} … … 202 205 203 206 \newenvironment{cquote}{% 204 \list{}{\ lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=4pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}%207 \list{}{\topsep=\lst@aboveskip\parskip=0pt\partopsep=0pt\itemsep=0pt\parsep=0pt\listparindent=0pt\leftmargin=\parindentlnth\rightmargin=0pt}% 205 208 \item\relax 209 \lstset{resetmargins=true} 206 210 }{% 207 211 \endlist … … 345 349 \fi% 346 350 351 \usepackage{tabularx} % if @ is used for lstMakeShortInline, allows @{} 352 347 353 % Local Variables: % 348 354 % tab-width: 4 % -
doc/LaTeXmacros/common.tex
r02c80cdc r4e08a54 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon Feb 26 08:06:05202414 %% Update Count : 6 1513 %% Last Modified On : Thu Apr 18 09:15:38 2024 14 %% Update Count : 664 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 109 109 \renewcommand\subparagraph{\@startsection{subparagraph}{4}{\z@}{-1.5ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries\itshape}} 110 110 111 % index macros112 111 \newcommand{\italic}[1]{\emph{\hyperpage{#1}}} 113 112 \newcommand{\Definition}[1]{\textbf{\hyperpage{#1}}} 114 \newcommand{\see}[1]{(see #1)} 113 \newcommand{\see}{\protect\@ifstar\@ssee\@see} 114 \newcommand{\@ssee}[1]{(See #1)} 115 \newcommand{\@see}[1]{(see #1)} 116 117 % index macros 115 118 116 119 % Define some commands that produce formatted index entries suitable for cross-references. … … 153 156 \newcommand{\newtermFontInline}{\emph} 154 157 \newcommand{\newterm}{\protect\@ifstar\@snewterm\@newterm} 158 \newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 155 159 \newcommand{\@newterm}[2][\@empty]{\lowercase{\def\temp{#2}}{\newtermFontInline{#2}}\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 156 \newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi}157 160 158 161 % \snake{<identifier>} … … 201 204 \newcommand{\VS}{\abbrevFont{vs}} 202 205 \newcommand{\vs}{\VS\CheckPeriod} 203 \makeatother204 206 205 207 \newenvironment{cquote}{% 206 \list{}{\ lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=4pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}%208 \list{}{\topsep=\lst@aboveskip\parskip=0pt\partopsep=0pt\itemsep=0pt\parsep=0pt\listparindent=0pt\leftmargin=\parindentlnth\rightmargin=0pt}% 207 209 \item\relax 210 \lstset{resetmargins=true} 208 211 }{% 209 212 \endlist 210 213 }% cquote 214 \makeatother 211 215 212 216 \newenvironment{rationale}{% … … 349 353 \fi% 350 354 355 \usepackage{tabularx} % if @ is used for lstMakeShortInline, allows @{} 356 351 357 % Local Variables: % 352 358 % tab-width: 4 % -
doc/LaTeXmacros/lstlang.sty
r02c80cdc r4e08a54 8 8 %% Created On : Sat May 13 16:34:42 2017 9 9 %% Last Modified By : Peter A. Buhr 10 %% Last Modified On : Tue Mar 12 17:29:58202411 %% Update Count : 4 210 %% Last Modified On : Mon Apr 15 11:28:44 2024 11 %% Update Count : 43 12 12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 13 … … 116 116 alignas, _Alignas, alignof, _Alignof, __alignof, __alignof__, and, asm, __asm, __asm__, _Atomic, __attribute, __attribute__, 117 117 __auto_type, basetypeof, _Bool, catch, catchResume, choose, coerce, corun, cofor, _Complex, __complex, __complex__, 118 __const, __const__, continue, _Decimal32, _Decimal64, _Decimal128, disable, dtype, enable, exception, __extension__,118 __const, __const__, continue, coroutine, _Decimal32, _Decimal64, _Decimal128, disable, dtype, enable, exception, __extension__, 119 119 fallthrough, fallthru, finally, fixup, __float80, float80, __float128, float128, _Float16, _Float32, _Float32x, _Float64, 120 120 _Float64x, _Float128, _Float128x, forall, fortran, ftype, generator, _Generic, _Imaginary, __imag, __imag__, inline, -
doc/bibliography/pl.bib
r02c80cdc r4e08a54 519 519 year = 1963, 520 520 pages = {1-17}, 521 } 522 523 @misc{AlgolW, 524 keywords = {AlgolW}, 525 contributer = {pabuhr@plg}, 526 author = {Henry Bauer and Sheldon Becker and Susan L. Graham and Edwin Satterthwaite and Richard L. Sites}, 527 title = {{Algol W} Language Description}, 528 month = jun, 529 year = 1972, 530 howpublished= {\url{https://www.algol60.org/docsW/algolw.pdf}}, 521 531 } 522 532 -
doc/theses/jiada_liang_MMath/CFAenum.tex
r02c80cdc r4e08a54 137 137 \section{Pure Enumerators} 138 138 139 An empty enumerator type, @enum()@, implies the enumerators are pure symbols without values but set properties;139 An empty enumerator type, @enum()@, implies the enumerators are opaque symbols without values but set properties; 140 140 hence, there is no default conversion to @int@. 141 141 -
doc/theses/jiada_liang_MMath/Makefile
r02c80cdc r4e08a54 13 13 BibSRC = ${wildcard *.bib} 14 14 15 TeXLIB = .:${LaTMac}:${Build}: 16 BibLIB = .:${BibRep}: 15 TeXLIB = .:${LaTMac}:${Build}: # common latex macros 16 BibLIB = .:${BibRep}: # common citation repository 17 17 18 18 MAKEFLAGS = --no-print-directory # --silent -
doc/theses/jiada_liang_MMath/background.tex
r02c80cdc r4e08a54 48 48 49 49 \section{C Enumeration} 50 \label{s:CEnumeration} 50 51 51 The C enumeration has the following syntax and semantics. 52 The C enumeration has the following syntax~\cite[\S~6.7.2.2]{C11}. 53 \begin{clang}[identifierstyle=\linespread{0.9}\it] 54 $\it enum$-specifier: 55 enum identifier$\(_{opt}\)$ { enumerator-list } 56 enum identifier$\(_{opt}\)$ { enumerator-list , } 57 enum identifier 58 enumerator-list: 59 enumerator 60 enumerator-list , enumerator 61 enumerator: 62 enumeration-constant 63 enumeration-constant = constant-expression 64 \end{clang} 65 The terms \emph{enumeration} and \emph{enumerator} used in this work \see{\VRef{s:Terminology}} come from the grammar. 66 The C enumeration semantics is discussed using examples. 67 68 An unnamed enumeration is used to provide secondary renaming, like a @const@ declaration in other languages. 69 \begin{clang} 70 enum { Size = 20, Pi = 3.14159 }; // unnamed enumeration $\(\Rightarrow\)$ no ordering 71 \end{clang} 72 This declaration form is not an enumeration even though it is declared using an @enum@ because it has none of the following enumeration properties. 73 74 A \emph{named} enumeration type is an actual enumeration. 52 75 \begin{clang} 53 76 enum Weekday { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun, }; -
doc/theses/jiada_liang_MMath/intro.tex
r02c80cdc r4e08a54 1 1 \chapter{Introduction} 2 2 3 All types in a programming language must have a set of constants, and these constants have \Newterm{primary names}, \eg integral types have constants @-1@, @17@, @12345@, \etc. 4 Constants can be overloaded among types, \eg @0@ is a null pointer for all pointer types, and the value zero for integral and floating-point types. 3 All types in a programming language must have a set of constants, and these constants have \Newterm{primary names}, \eg integral types have constants @-1@, @17@, @0xff@, floating-point types have constants @5.3@, @2.3E-5@, @0xff.ffp0@, character types have constants @'a'@, @"abc\n"@, \mbox{\lstinline{u8"}\texttt{\guillemotleft{na\"{i}ve}\guillemotright}\lstinline{"}}, \etc. 4 Con\-stants can be overloaded among types, \eg @0@ is a null pointer for all pointer types, and the value zero for integral and floating-point types. 5 (In \CFA, the primary constants @0@ and @1@ can be overloaded for any type.) 5 6 Hence, each primary constant has a symbolic name referring to its internal representation, and these names are dictated by language syntax related to types. 6 7 In theory, there are an infinite set of primary names per type. 7 8 8 \Newterm{Secondary naming} is a common practice in mathematics and engineering, \eg $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), MHz (1E6), and in general situations, \eg specific times (noon, New Years), cities (Big Apple), flowers (Lily), \etc.9 \Newterm{Secondary naming} is a common practice in mathematics, engineering and computer science, \eg $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), MB (mega byte, 1E6), and in general situations, \eg specific times (noon, New Years), cities (Big Apple), flowers (Lily), \etc. 9 10 Many programming languages capture this important software-engineering capability through a mechanism called \Newterm{constant} or \Newterm{literal} naming, where a secondary name is aliased to a primary name. 10 In some cases, secondary naming is \Newterm{pure}, where the matching internal representation can be chosen arbitrarily, and only equality operations are available, \eg @O_RDONLY@, @O_WRONLY@, @O_CREAT@, @O_TRUNC@, @O_APPEND@. 11 (The names the thing.) 11 Its common purpose is to eliminate duplication of the primary constant throughout a program. 12 For example, the secondary name replaces its primary name, thereafter changing the binding of the secondary to primary name automatically distributes the rebinding throughout the program. 13 In some cases, secondary naming is \Newterm{opaque}, where the matching internal representation can be chosen arbitrarily, and only equality operations are available, \eg @O_RDONLY@, @O_WRONLY@, @O_CREAT@, @O_TRUNC@, @O_APPEND@. 12 14 Because a secondary name is a constant, it cannot appear in a mutable context, \eg \mbox{$\pi$ \lstinline{= 42}} is meaningless, and a constant has no address, \ie it is an \Newterm{rvalue}\footnote{ 13 15 The term rvalue defines an expression that can only appear on the right-hand side of an assignment expression.}. … … 18 20 enumerate (verb, transitive). 19 21 To count, ascertain the number of; 20 \emph{more 21 usually, to mention (a number of things or persons) separately, as if for the 22 purpose of counting}; 23 to specify as in a list or catalogue.~\cite{OED} 22 more usually, to mention (a number of things or persons) separately, as if for the purpose of counting; 23 to specify as in a list or catalogue.~\cite{OEDenumerate} 24 24 \end{quote} 25 Within an enumeration set, the enumeration names must be unique, and instances of an enumerated type are restricted to hold only the secondary names.25 Within an enumeration set, the enumeration names must be unique, and instances of an enumerated type are \emph{often} restricted to hold only the secondary names. 26 26 It is possible to enumerate among set names without having an ordering among the set elements. 27 27 For example, the week, the weekdays, the weekend, and every second day of the week. … … 29 29 for ( cursor in Mon, Tue, Wed, Thu, Fri, Sat, Sun } ... $\C[3.75in]{// week}$ 30 30 for ( cursor in Mon, Tue, Wed, Thu, Fri } ... $\C{// weekday}$ 31 for ( cursor in Thu, Fri} ... $\C{// weekend}$31 for ( cursor in Sat, Sun } ... $\C{// weekend}$ 32 32 for ( cursor in Mon, Wed, Fri, Sun } ... $\C{// every second day of week}\CRT$ 33 33 \end{cfa} 34 This independence from internal representation allows multiple names to have the same representation (eight note, quaver), giving synonyms.34 This independence from internal representation allows multiple names to have the same representation (eighth note, quaver), giving synonyms. 35 35 A set can have a partial or total ordering, making it possible to compare set elements, \eg Monday is before Friday and Friday is after. 36 36 Ordering allows iterating among the enumeration set using relational operators and advancement, \eg … … 38 38 for ( cursor = Monday; cursor @<=@ Friday; cursor = @succ@( cursor ) ) ... 39 39 \end{cfa} 40 Here the internal representations for the secondary names are \emph{generated} rather than listing a subset of names. 40 Here the internal representations for the secondary names are logically \emph{generated} rather than listing a subset of names. 41 42 Hence, the fundamental aspects of an enumeration are: 43 \begin{enumerate} 44 \item 45 It defines a type from which instants can be generated. 46 \item 47 The type lists a finite set of secondary names, which become its primary constants. 48 This differentiates an enumeration from general types with an infinite number of primary constants. 49 \item 50 An enumeration's secondary names represent constants, which follows from their binding (aliasing) to primary names, which are constants. 51 \item 52 For safety, an enumeration instance is restricted to hold only its type's secondary names. 53 \item 54 There is a mechanism for \emph{enumerating} over the secondary names, where the ordering can be implicit from the type, explicitly listed, or generated arithmetically. 55 \end{enumerate} 41 56 42 57 43 58 \section{Terminology} 44 45 The term \Newterm{enumeration} defines the set of secondary names, and the term \Newterm{enumerator} represents an arbitrary secondary name. 59 \label{s:Terminology} 60 61 The term \Newterm{enumeration} defines a type with a set of secondary names, and the term \Newterm{enumerator} represents an arbitrary secondary name \see{\VRef{s:CEnumeration}}. 46 62 As well, an enumerated type has three fundamental properties, \Newterm{label}, \Newterm{order}, and \Newterm{value}. 47 63 \begin{cquote} … … 72 88 \section{Motivation} 73 89 74 Some programming languages only provide secondary renaming, which can be simulated by an enumeration without ordering. 75 \begin{cfa} 76 const Size = 20, Pi = 3.14159; 77 enum { Size = 20, Pi = 3.14159 }; // unnamed enumeration $\(\Rightarrow\)$ no ordering 78 \end{cfa} 79 In both cases, it is possible to compare the secondary names, \eg @Size < Pi@, if that is meaningful; 80 however, without an enumeration type-name, it is impossible to create an iterator cursor. 81 82 Secondary renaming can similate an enumeration, but with extra effort. 90 Some programming languages only provide direct secondary renaming. 91 \begin{cfa} 92 const Size = 20, Pi = 3.14159, Name = "Jane"; 93 \end{cfa} 94 Here, it is possible to compare the secondary names, \eg @Size < Pi@, if that is meaningful. 95 96 Secondary renaming can simulate an enumeration, but with extra effort. 83 97 \begin{cfa} 84 98 const Mon = 1, Tue = 2, Wed = 3, Thu = 4, Fri = 5, Sat = 6, Sun = 7; 85 99 \end{cfa} 86 Furthermore, reorderingthe enumerators requires manual renumbering.100 Any reordering of the enumerators requires manual renumbering. 87 101 \begin{cfa} 88 102 const Sun = 1, Mon = 2, Tue = 3, Wed = 4, Thu = 5, Fri = 6, Sat = 7; 89 103 \end{cfa} 90 Finally, there is no commontype to create a type-checked instance or iterator cursor.91 Hence, there is only a weak equivalence between secondary naming and enumerations, justifying the enumeration type in a programming language.92 93 A variant (algebraic) type is often promoted as a kind of enumeration, \ie a vari ent type can simulate an enumeration.94 A variant type is a tagged-union, where the possible types may beheterogeneous.95 \begin{cfa} 104 Finally, there is no type to create a type-checked instance or iterator cursor. 105 Hence, there is only a weak equivalence between secondary naming and enumerations, justifying a seperate enumeration type in a programming language. 106 107 A variant (algebraic) type is often promoted as a kind of enumeration, \ie a variant type can simulate an enumeration. 108 Fundamentally, a variant type is a tagged-union, where the tag is normally opaque and the types are usually heterogeneous. 109 \begin{cfa}[morekeywords={variant}] 96 110 @variant@ Variant { 97 111 @int tag;@ // optional/implicit: 0 => int, 1 => double, 2 => S … … 103 117 }; 104 118 \end{cfa} 105 Crucially, the union implies instance storage is shared by all of the variant types. 106 Hence, a variant is dynamically typed, as in a dynamic-typed programming-language, but the set of types is statically bound, similar to some aspects of dynamic gradual-typing~\cite{Gradual Typing}. 107 Knowing which type is in a variant instance is crucial for correctness. 108 Occasionally, it is possible to statically determine all regions where each variant type is used, so a tag and runtime checking is unnecessary; 109 otherwise, a tag is required to denote the particular type in the variant and the tag checked at runtime using some form of type pattern-matching. 110 111 The tag can be implicitly set by the compiler on assignment, or explicitly set by the program\-mer. 112 Type pattern-matching is then used to dynamically test the tag and branch to a section of code to safely manipulate the value, \eg: 119 Crucially, the union implies instance storage is shared by all the variant types, and therefore, before a variant type can be used in a statically-typed expression, it must be dynamically discriminated to its current contained type. 120 Hence, knowing which type is in a variant instance is crucial for correctness. 121 Occasionally, it is possible to statically determine all regions where each variant type is used, so a tag and runtime checking is unnecessary. 122 Otherwise, a tag is required to denote the particular type in the variant, and the tag is discriminated at runtime using some form of type pattern-matching, after which the value can be used in a statically-typed expression. 123 124 A less frequent variant case is multiple variants with the same type, which normally requires explicit naming of the tag to disambiguate among the common types. 125 \begin{cquote} 126 \begin{tabular}{@{}l@{\hspace{30pt}}l@{}} 127 \begin{cfa}[morekeywords={variant}] 128 variant VariantCT { 129 case @car@: int i; // explicitly typed 130 case @boat@: int i; 131 case @bridge@: int i; 132 }; 133 \end{cfa} 134 & 135 \begin{cfa}[morekeywords={variant}] 136 variant VariantCU { 137 case @car@: ; // empty or unit type 138 case @boat@: ; 139 case @bridge@: ; 140 }; 141 \end{cfa} 142 \end{tabular} 143 \end{cquote} 144 Here, the explicit tag name is used to give different meaning to the values in the common @int@ type, \eg the value 3 has different interpretations depending on the tag name. 145 It is even possible to remove the type or use the empty @unit@ type (@struct unit {}@). 146 It is this tag naming that is used to simulate an enumeration. 147 148 Normally, the variant tag is implicitly set by the compiler based on type, but with common types, a tag name is required to resolve type ambiguity. 149 \begin{cfa} 150 Variant v = 3; $\C{// implicitly set tag to 0 based on type of 3}$ 151 VariantCT ve = boats.3; $\C{// explicitly set tag to 1 using tag name}$ 152 \end{cfa} 153 Type pattern-matching is then used to dynamically test the tag and branch to a section of statically-typed code to safely manipulate the value, \eg: 154 \begin{cquote} 155 \begin{tabular}{@{}l@{\hspace{30pt}}l@{}} 113 156 \begin{cfa}[morekeywords={match}] 114 Variant v = 3; // implicitly set tag to 0 115 @match@( v ) { // know the type or test the tag 116 case int { /* only access i field in v */ } 117 case double { /* only access d field in v */ } 118 case S { /* only access s field in v */ } 157 @match@( v ) { // know type implicitly or test tag 158 case int { /* only access i field */ } 159 case double { /* only access d field */ } 160 case S { /* only access s field */ } 119 161 } 120 162 \end{cfa} 121 For safety, either all variant types must be listed or a @default@ case must exist with no field accesses. 122 123 To simulate an enumeration with a variant, the tag is \emph{re-purposed} for either ordering or value and the variant types are omitted. 124 \begin{cfa} 125 variant Weekday { 126 int tag; // implicit 0 => Mon, ..., 6 => Sun 127 @case Mon;@ // no type 163 & 164 \begin{cfa}[morekeywords={match}] 165 @match@( ve ) { 166 case car: int { /* car interpretation */ } 167 case boat: int { /* boat interpretation */ } 168 case bridge: int { /* bridge interpretation */ } 169 } 170 \end{cfa} 171 \end{tabular} 172 \end{cquote} 173 For safety, some languages require all variant types to be listed or a @default@ case with no field accesses. 174 175 To further strengthen the simulate for an enumeration with different values, each variant type can be a @const@ type or the tag becomes non-opaque, possibly taking advantage of the opaque auto-numbering. 176 \begin{cquote} 177 \begin{tabular}{@{}l@{\hspace{30pt}}l@{}} 178 \begin{cfa} 179 variant Week { 180 case Mon: const int = 0; 128 181 ... 129 @case Sun;@ 130 }; 131 \end{cfa} 132 The type system ensures tag setting and testing are correctly done. 133 However, the enumeration operations are limited to the available tag operations, \eg pattern matching. 134 \begin{cfa} 135 Week week = Mon; 136 if ( @dynamic_cast(Mon)@week ) ... // test tag == Mon 137 \end{cfa} 182 case Sat: const int = 5; 183 case Sun: const int = 10; 184 }; 185 \end{cfa} 186 & 187 \begin{cfa} 188 variant Week { 189 case Mon: ; // tag auto-numbering 190 ... 191 case Sat: ; 192 case @Sun = 10@: ; // directly set tag value 193 }; 194 \end{cfa} 195 \end{tabular} 196 \end{cquote} 197 Directly setting the tag implies restrictions, like unique values. 198 In both cases, instances of @Week@ are @const@ (immutable). 199 However, usage between these two types becomes complex. 200 \begin{cfa} 201 Week day = Week.Mon; // sets value or tag depending on type 202 if ( day == Week.Mon ) // dereference value or tag ? 203 \end{cfa} 204 Here, the dereference of @day@ should return the value of the type stored in the variant, never the tag. 205 If it does return the tag, some special meaning must be given to the empty/unit type, especially if a variant contains both regular and unit types. 206 207 208 In general, the enumeration simulation and the variant extensions to support it, are deviating from the normal use of a variant (union) type. 209 As well, the enumeration operations are limited to the available tag operations, \eg pattern matching. 138 210 While enumerating among tag names is possible: 139 211 \begin{cfa}[morekeywords={in}] 140 for ( cursor in Mon, Wed, Fri, Sun ) ... 141 \end{cfa} 142 ordering for iteration would require a \emph{magic} extension, such as a special @enum@ variant, because it has no meaning for a regular variant, \ie @int@ < @double@. 143 144 However, if a special @enum@ variant allows the tags to be heterogeneously typed, ordering must fall back on case positioning, as many types have incomparable values. 145 Iterating using tag ordering and heterogeneous types, also requires pattern matching. 146 \begin{cfa}[morekeywords={match}] 147 for ( cursor = Mon; cursor <= Fri; cursor = succ( cursor) ) { 148 match( cursor ) { 149 case Mon { /* access special type for Mon */ } 150 ... 151 case Fri { /* access special type for Fri */ } 152 default 153 } 154 } 155 \end{cfa} 156 If the variant type is changed by adding/removing types or the loop range changes, the pattern matching must be adjusted. 157 As well, if the start/stop values are dynamic, it may be impossible to statically determine if all variant types are listed. 158 159 Re-purposing the notion of enumerating into variant types is ill formed and confusing. 160 Hence, there is only a weak equivalence between an enumeration and variant type, justifying the enumeration type in a programming language. 212 for ( cursor in Week.Mon, Week.Wed, Week.Fri, Week.Sun ) ... 213 \end{cfa} 214 what is the type of @cursor@? 215 If it the tag type (@int@), how is this value used? 216 If it is the variant type, where is the instance variable, which only contains one value. 217 Hence, either enumerating with a variant enumeration is disallowed or some unusual typing rule must be invented to make it work but only in restricted contexts. 218 219 While functional programming systems regularly re-purposing variant types into enumeration types, this process seems contrived and confusing. 220 A variant tag is not an enumeration, it is a discriminant among a restricted set of types stored in a storage block. 221 Hence, there is only a weak equivalence between an enumeration and variant type, justifying a seperate enumeration type in a programming language. 161 222 162 223 -
doc/theses/jiada_liang_MMath/relatedwork.tex
r02c80cdc r4e08a54 53 53 \lstnewenvironment{ada}[1][]{\lstset{language=[2005]Ada,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},literate={'}{\ttfamily'\!}1}\lstset{#1}}{} 54 54 55 An Ada enumeration type is an ordered list of constants, called \Newterm{literals} (enumerators). 55 An Ada enumeration type is a set of ordered unscoped identifiers (enumerators) bound to \emph{unique} \Newterm{literals}.\footnote{% 56 Ada is \emph{case-insensitive} so identifiers may appear in multiple forms and still be the same, \eg \lstinline{Mon}, \lstinline{moN}, and \lstinline{MON} (a questionable design decision).} 56 57 \begin{ada} 57 type RGB is ( Red, Green, Blue ); -- 3literals (enumerators)58 type Week is ( Mon, Tue, Wed, Thu, Fri, Sat, Sun ); -- literals (enumerators) 58 59 \end{ada} 59 60 Object initialization and assignment are restricted to the enumerators of this type. 60 Enumerators without an explicitly designated constant value are auto-initialized: from left to right, starting at zero or the next explicitly initialized constant, incrementing by 1. 61 To explicitly set enumerator values, \emph{all} enumerators must be set in \emph{ascending} order, \ie there is no auto-initialization. 61 While Ada enumerators are unscoped, like C, Ada enumerators are overloadable. 62 62 \begin{ada} 63 type RGB is ( Red, Green, Blue ); 64 @for RGB use ( Red => 10, Green => 20, Blue => 30 );@ -- ascending order 65 \end{ada} 66 Hence, the position, value, label tuples are: 67 \begin{ada} 68 (0, 10, RED) (1, 20, GREEN) (2, 30, BLUE) 69 \end{ada} 70 Note, Ada is case-\emph{insensitive} so names may appear in multiple forms and still be the same, \eg @Red@ and @RED@ (a questionable design decision). 71 72 Like C, Ada enumerators are unscoped, \ie enumerators declared inside of an enum are visible (projected) into the enclosing scope. 73 The enumeration operators are the ordering operators, @=@, @<@, @<=@, @=@, @/=@, @>=@, @>@, where the ordering relationship is given implicitly by the sequence of enumerators, which is always ascending. 74 75 Ada enumerators are overloadable. 76 \begin{ada} 63 type RGB is ( @Red@, @Green@, Blue ); 77 64 type Traffic_Light is ( @Red@, Yellow, @Green@ ); 78 65 \end{ada} 79 Like \CFA, Ada uses an advanced type-resolution algorithm, including the left-hand side of assignment, to disambiguate among overloaded names.66 Like \CFA, Ada uses an advanced type-resolution algorithm, including the left-hand side of assignment, to disambiguate among overloaded identifiers. 80 67 \VRef[Figure]{f:AdaEnumeration} shows how ambiguity is handled using a cast, \ie \lstinline[language=ada]{RGB'(Red)}. 81 68 … … 102 89 \end{figure} 103 90 104 Ada provides an alias mechanism, \lstinline[language=ada]{renames}, for aliasing types, which is useful to shorten package names. 91 Enumerators without initialization are auto-initialized from left to right, starting at zero, incrementing by 1. 92 Enumerators with initialization must set \emph{all} enumerators in \emph{ascending} order, \ie there is no auto-initialization. 93 \begin{ada} 94 type Week is ( Mon, Tue, Wed, Thu, Fri, Sat, Sun ); 95 for Week use ( Mon => 0, Tue => 1, Wed => 2, Thu => @10@, Fri => 11, Sat => 14, Sun => 15 ); 96 \end{ada} 97 The enumeration operators are the equality and relational operators, @=@, @/=@, @<@, @<=@, @=@, @/=@, @>=@, @>@, where the ordering relationship is given implicitly by the sequence of acsending enumerators. 98 99 Ada provides an alias mechanism, \lstinline[language=ada]{renames}, for aliasing types, which is useful to shorten package identifiers. 105 100 \begin{ada} 106 101 OtherRed : RGB renames Red; … … 113 108 There are three pairs of inverse enumeration pseudo-functions (attributes): @'Pos@ and @'Val@, @'Enum_Rep@ and @'Enum_Val@, and @'Image@ and @'Value@, 114 109 \begin{cquote} 115 \lstDeleteShortInline@116 110 \setlength{\tabcolsep}{15pt} 117 111 \begin{tabular}{@{}ll@{}} … … 128 122 \end{ada} 129 123 \end{tabular} 130 \lstMakeShortInline@131 124 \end{cquote} 132 125 These attributes are important for IO. … … 138 131 \end{ada} 139 132 which is syntactic sugar for the label and not character literals from the predefined type @Character@. 140 The purpose is strictly readability using character literals rather than names.133 The purpose is strictly readability using character literals rather than identifiers. 141 134 \begin{ada} 142 135 Op : Operator := '+'; … … 171 164 An enumeration type can be used in the Ada \lstinline[language=ada]{case} (all enumerators must appear or a default) or iterating constructs. 172 165 \begin{cquote} 173 \lstDeleteShortInline@174 166 \setlength{\tabcolsep}{15pt} 175 167 \begin{tabular}{@{}ll@{}} … … 211 203 \end{ada} 212 204 \end{tabular} 213 \lstMakeShortInline@214 205 \end{cquote} 215 206 … … 229 220 \CC has the equivalent of Pascal typed @const@ declarations \see{\VRef{s:Pascal}}, with static and dynamic initialization. 230 221 \begin{c++} 231 const auto one = 0 + 1; $\C{// static in tialization}$222 const auto one = 0 + 1; $\C{// static initialization}$ 232 223 const auto NULL = nullptr; 233 224 const auto PI = 3.14159; … … 237 228 Sat = Fri + 1, Sun = Sat + 1; 238 229 int sa[Sun]; 239 const auto r = random(); $\C{// dynamic in tialization}$230 const auto r = random(); $\C{// dynamic initialization}$ 240 231 int da[r]; $\C{// VLA}$ 241 232 \end{c++} … … 362 353 \begin{figure} 363 354 \centering 364 \lstDeleteShortInline@365 355 \begin{tabular}{@{}l|l@{}} 366 356 \multicolumn{1}{@{}c|}{non-object oriented} & \multicolumn{1}{c@{}}{object oriented} \\ … … 414 404 \end{csharp} 415 405 \end{tabular} 416 \lstMakeShortInline@417 406 \caption{\Csharp: Free Routine Versus Class Enumeration} 418 407 \label{CsharpFreeVersusClass} … … 429 418 const ( S = 0; T; USA = "USA"; U; V = 3.1; W ) $\C{// type change, implicit/explicit: 0 0 USA USA 3.1 3.1}$ 430 419 \end{Go} 431 Constant names are unscoped and must be unique (no overloading).420 Constant identifiers are unscoped and must be unique (no overloading). 432 421 The first enumerator \emph{must} be explicitly initialized; 433 422 subsequent enumerators can be implicitly or explicitly initialized. … … 459 448 Basic switch and looping are possible. 460 449 \begin{cquote} 461 \lstDeleteShortInline@462 450 \setlength{\tabcolsep}{15pt} 463 451 \begin{tabular}{@{}ll@{}} … … 482 470 \end{Go} 483 471 \end{tabular} 484 \lstMakeShortInline@485 472 \end{cquote} 486 473 However, the loop prints the values from 0 to 13 because there is no actual enumeration. … … 513 500 \begin{figure} 514 501 \centering 515 \lstDeleteShortInline@516 502 \begin{tabular}{@{}l|l@{}} 517 503 \multicolumn{1}{@{}c|}{non-object oriented} & \multicolumn{1}{c@{}}{object oriented} \\ … … 553 539 \end{Java} 554 540 \end{tabular} 555 \lstMakeShortInline@556 541 \caption{Java: Free Routine Versus Class Enumeration} 557 542 \label{f:JavaFreeVersusClass} … … 607 592 \section{Rust} 608 593 \lstnewenvironment{rust}[1][]{\lstset{language=Rust,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{} 594 % https://doc.rust-lang.org/reference/items/enumerations.html 609 595 610 596 Rust provides a scoped enumeration based on variant types. … … 1010 996 1011 997 1012 \section{Python }998 \section{Python 3.13} 1013 999 \lstnewenvironment{python}[1][]{\lstset{language=Python,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{} 1014 1015 A Python enumeration is a set of symbolic names bound to \emph{unique} values. 1016 They are similar to global variables, but offer a more useful @repr()@, grouping, type-safety, and additional features. 1017 Enumerations inherits from the @Enum@ class, \eg: 1018 \begin{python} 1019 class Weekday(@Enum@): Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7 1020 class RGB(@Enum@): Red = 1; Green = 2; Blue = 3 1021 \end{python} 1022 1023 Depending on the nature of the enum a member's value may or may not be important, but either way that value can be used to get the corresponding member: 1024 \begin{python} 1025 print( repr( Weekday( 3 ) ) ) 1026 <Weekday.Wed: 3> 1027 \end{python} 1028 As you can see, the @repr()@ of a member shows the enum name, the member name, and the value. 1029 The @str()@ of a member shows only the enum name and member name: 1030 \begin{python} 1031 print( str( Weekday.Thu ), Weekday.Thu ) 1032 Weekday.Thu Weekday.Thu 1033 \end{python} 1034 The type of an enumeration member is the enum it belongs to: 1035 \begin{python} 1036 print( type( Weekday.Thu ) ) 1037 <enum 'Weekday'> 1038 print( isinstance(Weekday.Fri, Weekday) ) 1039 True 1040 \end{python} 1041 Enum members have an attribute that contains just their name: 1042 \begin{python} 1043 print(Weekday.TUESDAY.name) 1044 TUESDAY 1045 \end{python} 1046 Likewise, they have an attribute for their value: 1047 \begin{python} 1048 Weekday.WEDNESDAY.value 1049 3 1050 \end{python} 1051 1052 Unlike many languages that treat enumerations solely as name/value pairs, Python @Enum@s can have behavior added. 1053 For example, @datetime.date@ has two methods for returning the weekday: @weekday()@ and @isoweekday()@. 1054 The difference is that one of them counts from 0-6 and the other from 1-7. 1055 Rather than keep track of that ourselves we can add a method to the @Weekday@ enum to extract the day from the date instance and return the matching enum member: 1056 \begin{python} 1057 class Weekday(Enum): Mon = 1; Tue = 2; Wed = 3; Thu = 10; Fri = 15; Sat = 16; Sun = 17 1058 $@$classmethod 1059 def from_date(cls, date): 1060 return cls(date.isoweekday()) 1061 \end{python} 1062 Now we can find out what today is! Observe: 1063 \begin{python} 1064 >>> from datetime import date 1065 >>> Weekday.from_date(date.today()) 1066 <Weekday.TUESDAY: 2> 1067 \end{python} 1068 Of course, if you're reading this on some other day, you'll see that day instead. 1069 1070 This Weekday enum is great if our variable only needs one day, but what if we need several? Maybe we're writing a function to plot chores during a week, and don't want to use a @list@ -- we could use a different type of @Enum@: 1071 \begin{python} 1072 from enum import Flag 1073 class WeekdayF(@Flag@): Mon = @1@; Tue = @2@; Wed = @4@; Thu = @8@; Fri = @16@; Sat = @32@; Sun = @64@ 1074 \end{python} 1075 We've changed two things: we're inherited from @Flag@, and the values are all powers of 2. 1000 % https://docs.python.org/3/howto/enum.html 1001 1002 Python is a dynamically-typed reflexive programming language with multiple versions, and hence, it is possible to extend existing or build new language features within the language. 1003 As a result, discussing Python enumerations is a moving target, because if a features does not exist, if can often be created with varying levels of complexity. 1004 Nevertheless, an attempt has been made to discuss core enumeration features that come with Python 3.13. 1005 1006 A Python enumeration type is a set of ordered scoped identifiers (enumerators) bound to \emph{unique} values. 1007 An enumeration is not a basic type; 1008 it is a @class@ inheriting from the @Enum@ class, where the enumerators must be explicitly initialized, \eg: 1009 \begin{python} 1010 class Week(@Enum@): Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7 1011 \end{python} 1012 and/or explicitly auto initialized, \eg: 1013 \begin{python} 1014 class Week(Enum): Mon = 1; Tue = 2; Wed = 3; Thu = 10; Fri = @auto()@; Sat = 4; Sun = @auto()@ 1015 \end{python} 1016 where @auto@ increments by 1 from the previous enumerator value. 1017 Object initialization and assignment are restricted to the enumerators of this type. 1018 An enumerator initialized with same value is an alias and invisible at the enumeration level, \ie the alias it substituted for its aliasee. 1019 \begin{python} 1020 class Week(Enum): Mon = 1; Tue = 2; Wed = 3; Thu = 10; Fri = @10@; Sat = @10@; Sun = @10@ 1021 \end{python} 1022 Here, the enumeration has only 4 enumerators and 3 aliases. 1023 An alias is only visible by dropping down to the @class@ level and asking for class members. 1024 @Enum@ only supports equality comparison between enumerator values; 1025 the extended class @OrderedEnum@ adds relational operators @<@, @<=@, @>@, and @>=@. 1026 1027 There are bidirectional enumeration pseudo-functions for label and value, but there is no concept of access using ordering (position). 1028 \begin{cquote} 1029 \setlength{\tabcolsep}{15pt} 1030 \begin{tabular}{@{}ll@{}} 1031 \begin{python} 1032 Week.Thu.value == 10; 1033 Week.Thu.name == 'Thu'; 1034 \end{python} 1035 & 1036 \begin{python} 1037 Week( 10 ) == Thu 1038 Week['Thu'].value = 10 1039 \end{python} 1040 \end{tabular} 1041 \end{cquote} 1042 1043 As an enumeration is a \lstinline[language=python]{class}, its own methods. 1044 \begin{python} 1045 class Week(Enum): 1046 Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7 1047 $\\@$classmethod 1048 def today(cls, date): 1049 return cls(date.isoweekday()) 1050 print( "today:", Week.today(date.today())) 1051 today: Week.Mon 1052 \end{python} 1053 The method @today@ retrieves the day of the week and uses it as an index to print out the corresponding label of @Week@. 1076 1054 1077 1055 @Flag@ allows combining several members into a single variable: 1078 1056 \begin{python} 1079 print( repr(Week dayF.Sat | WeekdayF.Sun) )1080 <Week dayF.Sun|Sat: 96>1057 print( repr(WeekF.Sat | WeekF.Sun) ) 1058 <WeekF.Sun|Sat: 96> 1081 1059 \end{python} 1082 1060 You can even iterate over a @Flag@ variable: … … 1084 1062 for day in weekend: 1085 1063 print(day) 1086 Week day.SATURDAY1087 Week day.SUNDAY1064 WeekF.Sat 1065 WeekF.Sun 1088 1066 \end{python} 1089 1067 Okay, let's get some chores set up: 1090 1068 \begin{python} 1091 1069 >>> chores_for_ethan = { 1092 ... 'feed the cat': Week day.MONDAY | Weekday.WEDNESDAY | Weekday.FRIDAY,1093 ... 'do the dishes': Week day.TUESDAY | Weekday.THURSDAY,1094 ... 'answer SO questions': Week day.SATURDAY,1070 ... 'feed the cat': Week.MONDAY | Week.WEDNESDAY | Week.FRIDAY, 1071 ... 'do the dishes': Week.TUESDAY | Week.THURSDAY, 1072 ... 'answer SO questions': Week.SATURDAY, 1095 1073 ... } 1096 1074 \end{python} … … 1101 1079 ... if day in days: 1102 1080 ... print(chore) 1103 >>> show_chores(chores_for_ethan, Week day.SATURDAY)1081 >>> show_chores(chores_for_ethan, Week.SATURDAY) 1104 1082 answer SO questions 1105 1083 \end{python} 1106 In cases where the actual values of the members do not matter, you can save yourself some work and use @auto()@ for the values: 1107 \begin{python} 1108 >>> from enum import auto 1109 >>> class Weekday(Flag): 1110 ... MONDAY = auto() 1111 ... TUESDAY = auto() 1112 ... WEDNESDAY = auto() 1113 ... THURSDAY = auto() 1114 ... FRIDAY = auto() 1115 ... SATURDAY = auto() 1116 ... SUNDAY = auto() 1117 ... WEEKEND = SATURDAY | SUNDAY 1084 Auto incrmenet for @Flag@ is by powers of 2. 1085 \begin{python} 1086 class WeekF(Flag): Mon = auto(); Tue = auto(); Wed = auto(); Thu = auto(); Fri = auto(); \ 1087 Sat = auto(); Sun = auto(); Weekend = Sat | Sun 1088 for d in WeekF: 1089 print( f"{d.name}: {d.value}", end=" ") 1090 Mon: 1 Tue: 2 Wed: 4 Thu: 8 Fri: 16 Sat: 32 Sun: 64 WeekA.Weekend 1118 1091 \end{python} 1119 1092 … … 1123 1096 @Enum@ allows such access: 1124 1097 \begin{python} 1125 >>> Color(1) 1126 <Color.RED: 1> 1127 >>> Color(3) 1128 <Color.BLUE: 3> 1098 print(RGB(1), RGB(3), ) 1099 RGB.RED RGB.GREEN 1129 1100 \end{python} 1130 1101 If you want to access enum members by name, use item access: 1131 1102 \begin{python} 1132 Color['RED'] 1133 <Color.RED: 1> 1134 1135 Color['GREEN'] 1136 <Color.GREEN: 2> 1103 print( RGBa['RED'], RGBa['GREEN'] ) 1104 RGB.RED RGB.GREEN 1137 1105 \end{python} 1138 1106 If you have an enum member and need its name or value: 1139 1107 \begin{python} 1140 >>> member = Color.RED 1141 >>> member.name 1142 'RED' 1143 >>> member.value 1144 1 1145 \end{python} 1146 1147 \subsection{Duplicating enum members and values} 1148 1149 An enum member can have other names associated with it. 1150 Given two entries @A@ and @B@ with the same value (and @A@ defined first), @B@ is an alias for the member @A@. 1151 By-value lookup of the value of @A@ will return the member @A@. 1152 By-name lookup of @A@ will return the member @A@. 1153 By-name lookup of @B@ will also return the member @A@: 1154 \begin{python} 1155 class Shape(Enum): SQUARE = 2; DIAMOND = 1; CIRCLE = 3; ALIAS_FOR_SQUARE = 2 1156 >>> Shape.SQUARE 1157 <Shape.SQUARE: 2> 1158 >>> Shape.ALIAS_FOR_SQUARE 1159 <Shape.SQUARE: 2> 1160 >>> Shape(2) 1161 <Shape.SQUARE: 2> 1162 \end{python} 1163 1164 Note: Attempting to create a member with the same name as an already defined attribute (another member, a method, etc.) or attempting to create an attribute with the same name as a member is not allowed. 1108 member = RGBa.RED 1109 print( f"{member.name} {member.value}" ) 1110 RED 1 1111 \end{python} 1112 1165 1113 1166 1114 \subsection{Ensuring unique enumeration values} … … 1207 1155 >>> list(Shape) 1208 1156 [<Shape.SQUARE: 2>, <Shape.DIAMOND: 1>, <Shape.CIRCLE: 3>] 1209 >>> list(Week day)1210 [<Week day.MONDAY: 1>, <Weekday.TUESDAY: 2>, <Weekday.WEDNESDAY: 4>, <Weekday.THURSDAY: 8>,1211 <Week day.FRIDAY: 16>, <Weekday.SATURDAY: 32>, <Weekday.SUNDAY: 64>]1212 \end{python} 1213 Note that the aliases @Shape.ALIAS_FOR_SQUARE@ and @Week day.WEEKEND@ aren't shown.1157 >>> list(Week) 1158 [<Week.MONDAY: 1>, <Week.TUESDAY: 2>, <Week.WEDNESDAY: 4>, <Week.THURSDAY: 8>, 1159 <Week.FRIDAY: 16>, <Week.SATURDAY: 32>, <Week.SUNDAY: 64>] 1160 \end{python} 1161 Note that the aliases @Shape.ALIAS_FOR_SQUARE@ and @Week.WEEKEND@ aren't shown. 1214 1162 1215 1163 The special attribute @__members__@ is a read-only ordered mapping of names to members. … … 2218 2166 2219 2167 OCaml provides a variant (union) type, where multiple heterogeneously-typed objects share the same storage. 2220 The simplest form of the variant type is a list of nullary datatype constructors, which is like an unscoped, pure enumeration. 2221 2222 (I think the value of a ocaml variants are types not object, so I am not sure about this line) 2168 The simplest form of the variant type is a list of nullary datatype constructors, which is like an unscoped, opaque enumeration. 2169 2223 2170 OCaml provides a variant (union) type, which is an aggregation of heterogeneous types. 2224 A basic variant is a list of nullary datatype constructors, which is like an unscoped, pure enumeration.2171 A basic variant is a list of nullary datatype constructors, which is like an unscoped, opaque enumeration. 2225 2172 \begin{ocaml} 2226 2173 type weekday = Mon | Tue | Wed | Thu | Fri | Sat | Sun … … 2246 2193 type colour = Red | Green of @string@ | Blue of @int * float@ 2247 2194 \end{ocaml} 2248 A variant with parameter is stored in a memory block, prefixed by an int tag and has its parameters stores as words in the block. 2195 A variant with parameter is stored in a memory block, prefixed by an int tag and has its parameters stores as words in the block. 2249 2196 @colour@ is a summation of a nullary type, a unary product type of @string@, and a cross product of @int@ and @float@. 2250 2197 (Mathematically, a @Blue@ value is a Cartesian product of the types @int@ type and @float@.) … … 2259 2206 @Red, abc, 1 1.5@ 2260 2207 \end{ocaml} 2261 2262 2208 2263 2209 A variant type can have a recursive definition. … … 2280 2226 2281 2227 In summary, an OCaml variant is a singleton value rather than a set of possibly ordered values, and hence, has no notion of enumerabilty. 2282 Therefore it is not an enumeration, except for the simple pure (nullary) case.2228 Therefore it is not an enumeration, except for the simple opaque (nullary) case. 2283 2229 2284 2230 \begin{comment} … … 2466 2412 With valediction, 2467 2413 - Gregor Richards 2414 2415 2416 Date: Tue, 16 Apr 2024 11:04:51 -0400 2417 Subject: Re: C unnamed enumeration 2418 To: "Peter A. Buhr" <pabuhr@uwaterloo.ca> 2419 CC: <ajbeach@uwaterloo.ca>, <j82liang@uwaterloo.ca>, <mlbrooks@uwaterloo.ca>, 2420 <f37yu@uwaterloo.ca> 2421 From: Gregor Richards <gregor.richards@uwaterloo.ca> 2422 2423 On 4/16/24 09:55, Peter A. Buhr wrote: 2424 > So what is a variant? Is it a set of tag names, which might be a union or is it 2425 > a union, which might have tag names? 2426 2427 Your tagless variant bears no resemblance to variants in any functional 2428 programming language. A variant is a tag AND a union. You might not need to put 2429 anything in the union, in which case it's a pointless union, but the named tag 2430 is absolutely mandatory. That's the thing that varies. 2431 2432 I was unaware of std::variant. As far as functional languages are concerned, 2433 std::variant IS NOT A VARIANT. Perhaps it would be best to use the term ADT for 2434 the functional language concept, because that term has no other meanings. 2435 2436 An ADT cannot not have a named tag. That's meaningless. The tag is the data 2437 constructor, which is the thing you actually define when you define an ADT. It 2438 is strictly the union that's optional. 2439 2440 With valediction, 2441 - Gregor Richards 2468 2442 \end{comment} 2469 2443 … … 2487 2461 \hline 2488 2462 \hline 2489 pure & & & & & & & & & & & & & \CM \\2463 opaque & & & & & & & & & & & & & \CM \\ 2490 2464 \hline 2491 2465 typed & & & & & & & & & & & @int@ & integral & @T@ \\ -
doc/theses/jiada_liang_MMath/uw-ethesis.bib
r02c80cdc r4e08a54 2 2 % For use with BibTeX 3 3 4 Oxford English Dictionary, s.v. ``enumerate (v.), sense 3,'' September 2023, https://doi.org/10.1093/OED/1113960777. 5 @misc{OEDenumerate, 6 keywords = {enumerate}, 7 key = {enumerate}, 8 title = {enumerate (v.), sense 3}, 9 author = {Oxford English Dictionary}, 10 howpublished= {\url{https://doi.org/10.1093/OED/1113960777}}, 11 month = sep, 12 year = 2023, 13 } -
doc/uC++toCFA/Makefile
r02c80cdc r4e08a54 56 56 dvips ${Build}/$< -o $@ 57 57 58 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \59 ${Macros}/ common.sty ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib build/version | ${Build}58 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${Macros}/common.tex ${Macros}/common.sty \ 59 ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib build/version | ${Build} 60 60 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 61 61 if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi -
doc/uC++toCFA/uC++toCFA.tex
r02c80cdc r4e08a54 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Thu Jan 11 14:46:14202414 %% Update Count : 59 4213 %% Last Modified On : Sat Apr 13 11:11:39 2024 14 %% Update Count : 5969 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 141 141 \CFA uses parametric polymorphism and allows overloading of variables and routines: 142 142 \begin{cfa} 143 int i; char i; double i; // overload name i143 int i; char i; double i; $\C[2in]{// overload name i}$ 144 144 int i(); double i(); char i(); 145 i += 1; $\C[1.5in]{// int i}$146 i += 1.0; $\C{// double i}$147 i += 'a'; $\C{// char i}$148 int j = i(); $\C{// int i()}$149 double j = i(); $\C{// double i();}$150 char j = i(); $\C{// char i()}\CRT$145 i += 1; $\C{// int i}$ 146 i += 1.0; $\C{// double i}$ 147 i += 'a'; $\C{// char i}$ 148 int j = i(); $\C{// int i()}$ 149 double j = i(); $\C{// double i();}$ 150 char j = i(); $\C{// char i()}\CRT$ 151 151 \end{cfa} 152 152 \CFA has rebindable references. 153 154 \begin{cquote} 155 \begin{tabular}{l|l} 156 \multicolumn{2}{l}{\lstinline{ int x = 1, y = 2, * p1x = &x, * p1y = &y, ** p2i = &p1x,}} \\ 157 \multicolumn{2}{l}{\lstinline{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ && r1x = x, & r1y = y, && r2i = r1x;}} \\ 153 \begin{cquote} 154 \begin{tabular}{@{}l|l@{}} 155 \multicolumn{2}{@{}l}{\lstinline{ int x = 1, y = 2, * p1x = &x, * p1y = &y, ** p2i = &p1x,}} \\ 156 \multicolumn{2}{@{}l}{\lstinline{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ && r1x = x, & r1y = y, && r2i = r1x;}} \\ 158 157 \begin{uC++} 159 158 **p2i = 3; … … 201 200 202 201 \CFA output streams automatically separate values and insert a newline at the end of the print. 203 204 \begin{cquote} 205 \begin{tabular}{l|l} 202 \begin{cquote} 203 \begin{tabular}{@{}l|l@{}} 206 204 \begin{uC++} 207 205 #include <@iostream@> … … 226 224 227 225 \begin{cquote} 228 \begin{tabular}{ l|l}226 \begin{tabular}{@{}l|l@{}} 229 227 \begin{uC++} 230 228 for ( @;;@ ) { ... } / while ( @true@ ) { ... } … … 280 278 Currently, \CFA uses macros @ExceptionDecl@ and @ExceptionInst@ to declare and instantiate an exception. 281 279 \begin{cquote} 282 \begin{tabular}{ l|ll}280 \begin{tabular}{@{}l|ll@{}} 283 281 \begin{uC++} 284 282 … … 321 319 322 320 \begin{cquote} 323 \begin{tabular}{ l|ll}321 \begin{tabular}{@{}l|ll@{}} 324 322 \begin{uC++} 325 323 … … 360 358 361 359 \begin{cquote} 362 \begin{tabular}{ l|l}360 \begin{tabular}{@{}l|l@{}} 363 361 \begin{uC++} 364 362 struct S { … … 383 381 384 382 \begin{cquote} 385 \begin{tabular}{ l|l}386 \multicolumn{2}{ l}{\lstinline{string s1, s2;}} \\383 \begin{tabular}{@{}l|l@{}} 384 \multicolumn{2}{@{}l@{}}{\lstinline{string s1, s2;}} \\ 387 385 \begin{uC++} 388 386 s1 = "hi"; … … 425 423 426 424 \begin{cquote} 427 \begin{tabular}{ l|l}425 \begin{tabular}{@{}l|l@{}} 428 426 \begin{uC++} 429 427 struct S { … … 456 454 457 455 \begin{cquote} 458 \begin{tabular}{ l|l}456 \begin{tabular}{@{}l|l@{}} 459 457 \begin{uC++} 460 458 … … 493 491 494 492 \begin{cquote} 495 \begin{tabular}{ l|ll}493 \begin{tabular}{@{}l|ll@{}} 496 494 \begin{uC++} 497 495 … … 532 530 533 531 \begin{cquote} 534 \begin{tabular}{ l|ll}532 \begin{tabular}{@{}l|ll@{}} 535 533 \begin{uC++} 536 534 … … 567 565 568 566 \begin{cquote} 569 \begin{tabular}{ l|ll}567 \begin{tabular}{@{}l|ll@{}} 570 568 \begin{uC++} 571 569 … … 604 602 605 603 \begin{cquote} 606 \begin{tabular}{ l|ll}604 \begin{tabular}{@{}l|ll@{}} 607 605 \begin{uC++} 608 606 -
doc/user/Makefile
r02c80cdc r4e08a54 60 60 dvips ${Build}/$< -o $@ 61 61 62 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \63 ${Macros}/ common.sty ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib build/version | ${Build}62 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${Macros}/common.tex ${Macros}/common.sty \ 63 ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib build/version | ${Build} 64 64 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 65 65 if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi … … 73 73 makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx 74 74 # Run again to finish citations 75 ${LaTeX} ${basename $@}.tex75 # ${LaTeX} ${basename $@}.tex 76 76 # Run again to get index title into table of contents 77 77 # ${LaTeX} ${basename $@}.tex -
doc/user/user.tex
r02c80cdc r4e08a54 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon Feb 12 11:50:26202414 %% Update Count : 6 19913 %% Last Modified On : Thu Apr 18 21:53:45 2024 14 %% Update Count : 6502 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 130 130 \vspace*{\fill} 131 131 \noindent 132 \copyright\,2016, 2018, 2021 \CFA Project \\ \\132 \copyright\,2016, 2018, 2021, 2024 \CFA Project \\ \\ 133 133 \noindent 134 134 This work is licensed under the Creative Commons Attribution 4.0 International License. … … 312 312 For example, it is possible to write a type-safe \CFA wrapper ©malloc© based on the C ©malloc©: 313 313 \begin{cfa} 314 forall( dtype T| sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); }314 forall( T & | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); } 315 315 int * ip = malloc(); §\C{// select type and size from left-hand side}§ 316 316 double * dp = malloc(); … … 1023 1023 while () { sout | "empty"; break; } 1024 1024 do { sout | "empty"; break; } while (); 1025 for () { sout | "empty"; break; } §\C{sout | nl | nlOff;}§1026 1027 for ( 0 ) { sout | "A"; } sout | "zero"; §\C{sout | nl;}§1028 for ( 1 ) { sout | "A"; } §\C{sout | nl;}§1029 for ( 10 ) { sout | "A"; } §\C{sout | nl;}§1030 for ( ~= 10 ) { sout | "A"; } §\C{sout | nl;}§1031 for ( 1 ~= 10 ~ 2 ) { sout | "B"; } §\C{sout | nl;}§1032 for ( 1 -~= 10 ~ 2 ) { sout | "C"; } §\C{sout | nl;}§1033 for ( 0.5 ~ 5.5 ) { sout | "D"; } §\C{sout | nl;}§1034 for ( 0.5 -~ 5.5 ) { sout | "E"; } §\C{sout | nl;}§1035 for ( i; 10 ) { sout | i; } §\C{sout | nl;}§1036 for ( i; ~= 10 ) { sout | i; } §\C{sout | nl;}§1037 for ( i; 1 ~= 10 ~ 2 ) { sout | i; } §\C{sout | nl;}§1038 for ( i; 1 -~= 10 ~ 2 ) { sout | i; } §\C{sout | nl;}§1039 for ( i; 0.5 ~ 5.5 ) { sout | i; } §\C{sout | nl;}§1040 for ( i; 0.5 -~ 5.5 ) { sout | i; } §\C{sout | nl;}§1041 for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; } §\C{sout | nl;}§1042 for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; } §\C{sout | nl | nl | nl;}§1025 for () { sout | "empty"; break; } §\C[3in]{sout | nl | nlOff;}§ 1026 1027 for ( 0 ) { sout | "A"; } sout | "zero"; §\C{sout | nl;}§ 1028 for ( 1 ) { sout | "A"; } §\C{sout | nl;}§ 1029 for ( 10 ) { sout | "A"; } §\C{sout | nl;}§ 1030 for ( ~= 10 ) { sout | "A"; } §\C{sout | nl;}§ 1031 for ( 1 ~= 10 ~ 2 ) { sout | "B"; } §\C{sout | nl;}§ 1032 for ( 1 -~= 10 ~ 2 ) { sout | "C"; } §\C{sout | nl;}§ 1033 for ( 0.5 ~ 5.5 ) { sout | "D"; } §\C{sout | nl;}§ 1034 for ( 0.5 -~ 5.5 ) { sout | "E"; } §\C{sout | nl;}§ 1035 for ( i; 10 ) { sout | i; } §\C{sout | nl;}§ 1036 for ( i; ~= 10 ) { sout | i; } §\C{sout | nl;}§ 1037 for ( i; 1 ~= 10 ~ 2 ) { sout | i; } §\C{sout | nl;}§ 1038 for ( i; 1 -~= 10 ~ 2 ) { sout | i; } §\C{sout | nl;}§ 1039 for ( i; 0.5 ~ 5.5 ) { sout | i; } §\C{sout | nl;}§ 1040 for ( i; 0.5 -~ 5.5 ) { sout | i; } §\C{sout | nl;}§ 1041 for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; } §\C{sout | nl;}§ 1042 for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; } §\C{sout | nl | nl | nl;}§ 1043 1043 1044 1044 enum { N = 10 }; 1045 for ( N ) { sout | "N"; } §\C{sout | nl;}§1046 for ( i; N ) { sout | i; } §\C{sout | nl;}§1047 for ( i; -~ N ) { sout | i; } §\C{sout | nl | nl | nl;}§1045 for ( N ) { sout | "N"; } §\C{sout | nl;}§ 1046 for ( i; N ) { sout | i; } §\C{sout | nl;}§ 1047 for ( i; -~ N ) { sout | i; } §\C{sout | nl | nl | nl;}§ 1048 1048 1049 1049 const int low = 3, high = 10, inc = 2; 1050 for ( i; low ~ high ~ inc + 1 ) { sout | i; } §\C{sout | nl;}§1051 for ( i; 1 ~ @ ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§1052 for ( i; @ -~ 10 ) { if ( i < 0 ) break; sout | i; } §\C{sout | nl;}§1053 for ( i; 2 ~ @ ~ 2 ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§1050 for ( i; low ~ high ~ inc + 1 ) { sout | i; } §\C{sout | nl;}§ 1051 for ( i; 1 ~ @ ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§ 1052 for ( i; @ -~ 10 ) { if ( i < 0 ) break; sout | i; } §\C{sout | nl;}§ 1053 for ( i; 2 ~ @ ~ 2 ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§ 1054 1054 for ( i; 2.1 ~ @ ~ @ ) { if ( i > 10.5 ) break; sout | i; i += 1.7; } §\C{sout | nl;}§ 1055 1055 for ( i; @ -~ 10 ~ 2 ) { if ( i < 0 ) break; sout | i; } §\C{sout | nl;}§ 1056 1056 for ( i; 12.1 ~ @ ~ @ ) { if ( i < 2.5 ) break; sout | i; i -= 1.7; } §\C{sout | nl;}§ 1057 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } §\C{sout | nl;}§1058 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } §\C{sout | nl;}§1059 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } §\C{sout | nl;}§1060 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } §\C{sout | nl;}§1061 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } §\C{sout | nl;}§1062 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } §\C{sout | nl;}§1063 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } §\C{sout | nl;}§1064 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } §\C{sout | nl;}§1057 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } §\C{sout | nl;}§ 1058 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } §\C{sout | nl;}§ 1059 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1060 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1061 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } §\C{sout | nl;}§ 1062 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } §\C{sout | nl;}§ 1063 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1064 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1065 1065 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§ 1066 1066 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§ 1067 for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;} §1067 for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;}\CRT§ 1068 1068 \end{cfa} 1069 1069 & … … 2960 2960 The string ``©int (*f(x))[ 5 ]©'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``©[ 5 ] int x©'' declares a \CFA style parameter ©x© of type array of 5 integers. 2961 2961 Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string. 2962 2963 {\color{red} 2962 2964 As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity: 2963 2965 \begin{cfa} … … 2967 2969 The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo. 2968 2970 The redefinition of a type name in a parameter list is the only context in C where the character ©*© can appear to the left of a type name, and \CFA relies on all type qualifier characters appearing to the right of the type name. 2969 The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts. 2971 The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts.} 2970 2972 2971 2973 C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg: … … 3055 3057 static [ int ] g ( int ); 3056 3058 \end{cfa} 3059 3060 3061 \subsection{Postfix Function} 3062 \label{s:PostfixFunction} 3063 3064 \CFA provides an alternative call syntax where the argument appears before the function name. 3065 The syntax uses the backquote ©`© to separate the parameters/arguments and function name: ©?`© denotes a postfix-function name, \eg ©int ?`h( int s )© and ©`© denotes a postfix-function call, \eg ©0`h© meaning ©h( 0 )©. 3066 \begin{cquote} 3067 \begin{tabular}{@{}l|l|l|l@{}} 3068 postfix function & constant argument call & variable argument call & postfix function pointer \\ 3069 \hline 3070 \begin{cfa} 3071 int ?`h( int s ); 3072 int ?`h( double s ); 3073 int ?`m( char c ); 3074 int ?`m( const char * s ); 3075 int ?`t( int a, int b, int c ); 3076 \end{cfa} 3077 & 3078 \begin{cfa} 3079 0`h; 3080 3.5`h; 3081 '1'`m; 3082 "123" "456"`m; 3083 [1,2,3]`t; 3084 \end{cfa} 3085 & 3086 \begin{cfa} 3087 int i = 7; 3088 i`h; 3089 (i + 3)`h; 3090 (i + 3.5)`h; 3091 \end{cfa} 3092 & 3093 \begin{cfa} 3094 int (* ?`p)( int i ); 3095 ?`p = ?`h; 3096 3`p; 3097 i`p; 3098 (i + 3)`p; 3099 \end{cfa} 3100 \end{tabular} 3101 \end{cquote} 3102 3103 \VRef[Figure]{f:UnitsComparison} shows a common usage for postfix functions: converting basic literals into user literals. 3104 \see*{\VRef{s:DynamicStorageManagement} for other uses for postfix functions.} 3105 The \CFA example (left) stores a mass in units of stones (1 stone = 14 lb or 6.35 kg) and provides an addition operator (imagine a full set of arithmetic operators). 3106 The three postfixing function names ©st©, ©lb©, and ©kg©, represent units stones, pounds, and kilograms, respectively. 3107 Each name has two forms that bidirectional convert: a value of a specified unit to stones, \eg ©w = 14`lb© $\Rightarrow$ ©w == 1© stone or a ©Weight© from stones back to specific units, \eg ©w`lb© (1 stone) to ©14©. 3108 All arithmetic operations manipulate stones and the postfix operations convert to the different units. 3109 A similar group of postfix functions provide user constants for converting time units into nanoseconds, which is the basic time unit, \eg ©ns©, ©us©, ©ms©, ©s©, ©m©, ©h©, ©d©, and ©w©, for nanosecond, microsecond, millisecond, second, minute, hour, day, and week, respectively. 3110 (Note, month is not a fixed period of time nor is year because of leap years.) 3111 3112 \begin{figure} 3113 \centering 3114 \begin{tabular}{@{}l|l@{}} 3115 \multicolumn{1}{@{}c|}{\textbf{\CFA Postfix Routine}} & \multicolumn{1}{c@{}}{\textbf{\CC User Literals}} \\ 3116 \hline 3117 \begin{cfa} 3118 struct Weight { 3119 double stones; 3120 }; 3121 3122 3123 Weight ?+?( Weight l, Weight r ) { 3124 return l.stones + r.stones; 3125 } 3126 Weight ?`st( double w ) { return w; } 3127 double ?`st( Weight w ) { return w.stones; } 3128 Weight ?`lb( double w ) { return w / 14.0; } 3129 double ?`lb( Weight w ) { return w.stones * 14.0; } 3130 Weight ?`kg( double w ) { return w / 6.35; } 3131 double ?`kg( Weight w ) { return w.stones * 6.35; } 3132 int main() { 3133 Weight w, heavy = { 20 }; // stones 3134 w = 155`lb; 3135 w = 0b_1111`st; 3136 w = 0_233`lb; 3137 w = 0x_9b`kg; 3138 w = 5.5`st + 8`kg + 25.01`lb + heavy; 3139 } 3140 \end{cfa} 3141 & 3142 \begin{C++} 3143 struct Weight { 3144 double stones; 3145 Weight() {} 3146 Weight( double w ) { stones = w; } 3147 }; 3148 Weight operator+( Weight l, Weight r ) { 3149 return l.stones + r.stones; 3150 } 3151 Weight operator""_st( long double w ) { return w; } 3152 Weight operator""_lb( long double w ) { return w / 14.0; } 3153 Weight operator""_kg( long double w ) { return w / 6.35; } 3154 Weight operator""_st( unsigned long long int w ) { return w; } 3155 Weight operator""_lb( unsigned long long int w ) { return w / 14.0; } 3156 Weight operator""_kg( unsigned long long int w ) { return w / 6.35; } 3157 int main() { 3158 Weight w, heavy = { 20 }; // stones 3159 w = 155_lb; 3160 w = 0b1111_st; 3161 w = 0'233_lb; // quote separator 3162 w = 0x9b_kg; 3163 w = 5.5_st + 8_kg + 25.01_lb + heavy; 3164 } 3165 \end{C++} 3166 \end{tabular} 3167 3168 \begin{comment} 3169 Time : comparison of time units. \\ 3170 \begin{tabular}{@{}ll@{}} 3171 \CFA & \CC \\ 3172 \begin{cfa} 3173 #include <fstream.hfa> 3174 #include <time.hfa> 3175 3176 3177 Duration s = 1`h + 2 * 10`m + 70`s / 10; 3178 sout | "1 hour + 2*10 min + 70/10 sec = " | s | "seconds"; 3179 sout | "Dividing that by 2 minutes gives" | s / 2`m; 3180 sout | "Dividing that by 2 gives" | s / 2 | "seconds\n"; 3181 sout | s | "seconds is" 3182 | s`h | "hours," 3183 | (s % 1`h)`m | "minutes," 3184 | (s % 1`m)`s | "seconds"; 3185 \end{cfa} 3186 & 3187 \begin{C++} 3188 #include <iostream> 3189 #include <chrono> 3190 using namespace std; 3191 using namespace std::chrono; 3192 seconds s = hours(1) + 2 * minutes(10) + seconds(70) / 10; 3193 cout << "1 hour + 2*10 min + 70/10 sec = " << s.count() << " seconds\n"; 3194 cout << "Dividing that by 2 minutes gives " << s / minutes(2) << '\n'; 3195 cout << "Dividing that by 2 gives " << (s / 2).count() << " seconds\n"; 3196 cout << s.count() << " seconds is " 3197 << duration_cast<hours>( s ).count() << " hours, " 3198 << duration_cast<minutes>( s % hours(1) ).count() << " minutes, " 3199 << duration_cast<seconds>( s % minutes(1) ).count() << " seconds\n"; 3200 \end{C++} 3201 \end{tabular} 3202 \end{comment} 3203 3204 \caption{Units: Stone, Pound, Kilogram Comparison} 3205 \label{f:UnitsComparison} 3206 \end{figure} 3207 3208 The \CC example (right) provides a \emph{restricted} capability via user literals. 3209 The \lstinline[language=C++]{operator ""} only takes a constant argument (\ie no variable argument), and the constant type must be the highest-level constant-type, \eg ©long double© for all floating-point constants. 3210 As well, there is no constant conversion, \ie ©int© to ©double© constants, so integral constants are handled by a separate set of routines, with maximal integral type ©unsigned long long int©. 3211 Finally, there is no mechanism to use this syntax for a bidirectional conversion because \lstinline[language=C++]{operator ""} does not accept variable arguments. 3057 3212 3058 3213 … … 3809 3964 \subsection{Polymorphism} 3810 3965 3811 Due to the implicit flattening and structuring conversions involved in argument passing, ©otype© and ©dtype©parameters are restricted to matching only with non-tuple types.3966 Due to the implicit flattening and structuring conversions involved in argument passing, object and opaque parameters are restricted to matching only with non-tuple types. 3812 3967 The integration of polymorphism, type assertions, and monomorphic specialization of tuple-assertions are a primary contribution of this thesis to the design of tuples. 3813 3968 \begin{cfa} 3814 forall(T, dtype U)3969 forall(T, U &) 3815 3970 void f(T x, U * y); 3816 3971 … … 4925 5080 sout | '1' | '2' | '3'; 4926 5081 sout | 1 | "" | 2 | "" | 3; 4927 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x Â¥"4928 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10;5082 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥" 5083 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10; 4929 5084 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x" 4930 | 7 | " ¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x";5085 | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x"; 4931 5086 sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx"; 4932 5087 sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4; … … 7775 7930 \item[Rationale:] increase type safety 7776 7931 \item[Effect on original feature:] deletion of semantically well-defined feature. 7777 \item[Difficulty of converting:] requires adding a cast \see{\VRef{s: StorageManagement} for better alternatives}:7932 \item[Difficulty of converting:] requires adding a cast \see{\VRef{s:DynamicStorageManagement} for better alternatives}: 7778 7933 \begin{cfa} 7779 7934 int * b = (int *)malloc( sizeof(int) ); … … 7988 8143 \label{s:StandardLibrary} 7989 8144 7990 The \CFA standard-library wraps explicitly-polymorphic C routines into implicitly-polymorphic versions. 7991 7992 7993 \subsection{Storage Management} 7994 \label{s:StorageManagement} 7995 7996 The storage-management routines extend their C equivalents by overloading, alternate names, providing shallow type-safety, and removing the need to specify the allocation size for non-array types. 7997 7998 C storage management provides the following capabilities: 7999 \begin{description} 8000 \item[filled] 8001 after allocation with a specified character or value. 8145 The \CFA standard-library extends existing C library routines by adding new function, wrapping existing explicitly-polymorphic C routines into implicitly-polymorphic versions, and adding new \CFA extensions. 8146 8147 8148 \subsection{Dynamic Storage-Management} 8149 \label{s:DynamicStorageManagement} 8150 8151 Dynamic storage-management in C is based on explicit allocation and deallocation (©malloc©/©free©). 8152 Programmer's must manage all allocated storage via its address (pointer) and subsequently deallocate the storage via this address. 8153 Storage that is not deallocated becomes inaccessible, called a \newterm{memory leak}, which can only be detected at program termination. 8154 Storage freed twice is an error, called a \newterm{duplicate free}, which can sometimes be detected. 8155 Storage used after it is deallocated is an error, called using a \newterm{dangling pointer}, which can sometimes be detected. 8156 8157 8158 \subsubsection{C Interface} 8159 8160 C dynamic storage-management provides the following properties. 8161 \begin{description}[leftmargin=*] 8162 \item[fill] 8163 storage after an allocation with a specified character or value. 8164 \item[align] 8165 an allocation on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes. 8166 \item[scale] 8167 an allocation size to the specified number of array elements. 8168 An array may be filled, resized, or aligned. 8002 8169 \item[resize] 8003 8170 an existing allocation to decreased or increased its size. 8004 In either case, new storage may or may not be allocated and, if there is a new allocation, as much data from the existing allocation is copied into the new allocation. 8005 For an increase in storage size, new storage after the copied data may be filled. 8006 \item[align] 8007 an allocation on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes. 8008 \item[array] 8009 the allocation size is scaled to the specified number of array elements. 8010 An array may be filled, resized, or aligned. 8171 In either direction, new storage may or may not be allocated, but if there is a new allocation, as much data from the existing allocation is copied into the new allocation. 8172 When new storage is allocated, it may be aligned and storage after copied data may be filled. 8011 8173 \end{description} 8012 \VRef[Table]{t:AllocationVersusCapabilities} shows allocation routines supporting different combinations of storage-management capabilities. 8174 \VRef[Table]{t:AllocationVersusProperties} shows different combinations of storage-management properties provided by the C and \CFA allocation routines. 8175 8013 8176 \begin{table} 8177 \caption{Allocation Routines versus Storage-Management Properties} 8178 \label{t:AllocationVersusProperties} 8014 8179 \centering 8015 8180 \begin{minipage}{0.75\textwidth} 8016 8181 \begin{tabular}{@{}r|l|l|l|l|l@{}} 8017 \multicolumn{1}{c}{}& & \multicolumn{1}{c|}{fill} & resize & alignment & array\\8182 & \multicolumn{1}{c|}{routine} & \multicolumn{1}{c|}{\textbf{fill}} & \textbf{alignment} & \textbf{scale} & \textbf{resize} \\ 8018 8183 \hline 8019 8184 C & ©malloc© & no & no & no & no \\ 8020 & ©calloc© & yes (0 only) & no & no & yes \\ 8021 & ©realloc© & copy & yes & no & no \\ 8022 & ©memalign© & no & no & yes & no \\ 8023 & ©aligned_alloc©\footnote{Same as ©memalign© but size is an integral multiple of alignment, which is universally ignored.} 8024 & no & no & yes & no \\ 8025 & ©posix_memalign© & no & no & yes & no \\ 8026 & ©valloc© & no & no & yes (page size)& no \\ 8185 & ©calloc© & yes (0 only) & no & yes & no \\ 8186 & ©realloc© & copy & no & no & yes \\ 8187 & ©reallocarray© & copy & no & yes & yes \\ 8188 & ©memalign© & no & yes & no & no \\ 8189 & ©aligned_alloc©\footnote{Same as ©memalign© but size is an integral multiple of alignment.} 8190 & no & yes & no & no \\ 8191 & ©posix_memalign© & no & yes & no & no \\ 8192 & ©valloc© & no & yes (page size)& no & no \\ 8027 8193 & ©pvalloc©\footnote{Same as ©valloc© but rounds size to multiple of page size.} 8028 & no & no & yes (page size)& no \\ 8029 \hline 8030 \CFA & ©cmemalign© & yes (0 only) & no & yes & yes \\ 8031 & ©realloc© & copy & yes & yes & no \\ 8032 & ©alloc© & no & yes & no & yes \\ 8033 & ©alloc_set© & yes & yes & no & yes \\ 8034 & ©alloc_align© & no & yes & yes & yes \\ 8035 & ©alloc_align_set© & yes & yes & yes & yes \\ 8194 & no & yes (page size)& no & no \\ 8195 \hline 8196 \CFA & ©cmemalign© & yes (0 only) & yes & yes & no \\ 8197 & ©resize© & no copy & yes & no & yes \\ 8198 & ©realloc© & copy & yes & no & yes \\ 8199 & ©alloc©\footnote{Multiple overloads with different parameters.} 8200 & yes & yes & yes & yes 8036 8201 \end{tabular} 8037 8202 \end{minipage} 8038 \caption{Allocation Routines versus Storage-Management Capabilities} 8039 \label{t:AllocationVersusCapabilities} 8203 \vspace*{-10pt} 8040 8204 \end{table} 8041 8205 8042 \CFA memory management extends the type safety of all allocations by using the type of the left-hand-side type to determine the allocation size and return a matching type for the new storage. 8043 Type-safe allocation is provided for all C allocation routines and new \CFA allocation routines, \eg in 8044 \begin{cfa} 8045 int * ip = (int *)malloc( sizeof(int) ); §\C{// C}§ 8046 int * ip = malloc(); §\C{// \CFA type-safe version of C malloc}§ 8047 int * ip = alloc(); §\C{// \CFA type-safe uniform alloc}§ 8048 \end{cfa} 8049 the latter two allocations determine the allocation size from the type of ©p© (©int©) and cast the pointer to the allocated storage to ©int *©. 8050 8051 \CFA memory management extends allocation safety by implicitly honouring all alignment requirements, \eg in 8052 \begin{cfa} 8053 struct S { int i; } __attribute__(( aligned( 128 ) )); // cache-line alignment 8054 S * sp = malloc(); §\C{// honour type alignment}§ 8055 \end{cfa} 8056 the storage allocation is implicitly aligned to 128 rather than the default 16. 8057 The alignment check is performed at compile time so there is no runtime cost. 8058 8059 \CFA memory management extends the resize capability with the notion of \newterm{sticky properties}. 8060 Hence, initial allocation capabilities are remembered and maintained when resize requires copying. 8061 For example, an initial alignment and fill capability are preserved during a resize copy so the copy has the same alignment and extended storage is filled. 8062 Without sticky properties it is dangerous to use ©realloc©, resulting in an idiom of manually performing the reallocation to maintain correctness. 8063 \begin{cfa} 8064 8065 \end{cfa} 8066 8067 \CFA memory management extends allocation to support constructors for initialization of allocated storage, \eg in 8068 \begin{cfa} 8069 struct S { int i; }; §\C{// cache-line alignment}§ 8070 void ?{}( S & s, int i ) { s.i = i; } 8071 // assume ?|? operator for printing an S 8072 8073 S & sp = *®new®( 3 ); §\C{// call constructor after allocation}§ 8074 sout | sp.i; 8075 ®delete®( &sp ); 8076 8077 S * spa = ®anew®( 10, 5 ); §\C{// allocate array and initialize each array element}§ 8078 for ( i; 10 ) sout | spa[i] | nonl; 8079 sout | nl; 8080 ®adelete®( 10, spa ); 8206 8207 \subsubsection{\CFA Interface} 8208 8209 \CFA dynamic memory management: 8210 \begin{enumerate}[leftmargin=\parindent] 8211 \item 8212 Extend type safety of all allocation routines by using the left-hand assignment type to determine the allocation size and alignment, and return a matching type for the new storage, which removes many common allocation errors. 8213 \begin{cfa} 8214 int * ip = (int *)malloc( sizeof(int) ); §\C[2.3in]{// C}§ 8215 int * ip = malloc(); §\C{// \CFA type-safe call of C malloc}§ 8216 int * ip = alloc(); §\C{// \CFA type-safe call of \CFA alloc}§ 8217 struct __attribute__(( aligned(128) )) spinlock { ... }; 8218 spinlock * slp = malloc(); §\C{// correct size, alignment, and return type}\CRT§ 8219 \end{cfa} 8220 Here, the alignment of the ©ip© storage is 16 (default) and 128 for ©slp©. 8221 8222 \item 8223 Introduce the notion of \newterm{sticky properties} used in resizing. 8224 All initial allocation properties are remembered and maintained for use should resize require new storage. 8225 For example, the initial alignment and fill properties in the initial allocation 8226 \begin{cfa} 8227 struct __attribute__(( aligned(4096) )) S { ... }; 8228 S * sp = calloc( 10 ); §\C{// align 4K and zero fill}§ 8229 sp = reallocarray( sp, 100 ); §\C{// preserve 4K alignment and zero fill new storage}§ 8230 \end{cfa} 8231 are preserved in the resize so the new storage has the same alignment and extra storage after the data copy is zero filled. 8232 Without sticky properties it is dangerous to resize, resulting in the C idiom of manually performing the reallocation to maintain correctness, which is error prone. 8233 8234 \item 8235 Provide resizing without data copying, which is useful to repurpose an existing block of storage for another purpose, rather than freeing the old storage and performing a new allocation. 8236 The resize might be able to take advantage of unused storage after the data to preventing the free/reallocation step altogether. 8237 8238 \item 8239 Provide ©free©/©delete© functions that delete a variable number of pointers. 8240 \begin{cfa} 8241 int * ip = malloc(), * jp = malloc(), * kp = malloc(); 8242 double * xp = malloc(), * yp = malloc(), * zp = malloc(); 8243 free( ®ip, jp, kp, xp, yp, zp® ); 8244 \end{cfa} 8245 8246 \item 8247 Support constructors for initialization of allocated storage (like \CC) and destructors for deallocation. 8248 \begin{cfa} 8249 struct S { int v; }; §\C{// default constructors}§ 8250 void ^?{}( S & ) { ... } §\C{// destructor}§ 8251 S & sp = *®new®( 3 ); §\C{// allocate and call constructor}§ 8252 sout | sp.v; 8253 ®delete®( &sp ); §\C{// call destructor}§ 8254 S * spa1 = ®anew®( 10, 5 ), * spa2 = ®anew®( 10, 8 ); §\C{// allocate array and call constructor for each array element}§ 8255 for ( i; 10 ) sout | spa1[i].v | spa2[i].v | nonl; sout | nl; 8256 ®adelete®( spa1, spa2 ); §\C{// call destructors on all array objects}§ 8257 8258 3 8259 5 8 5 8 5 8 5 8 5 8 5 8 5 8 5 8 5 8 5 8 8081 8260 \end{cfa} 8082 8261 Allocation routines ©new©/©anew© allocate a variable/array and initialize storage using the allocated type's constructor. 8083 8262 Note, the matching deallocation routines ©delete©/©adelete©. 8084 8085 \leavevmode 8263 \end{enumerate} 8264 8265 In addition, \CFA provides a new allocator interface to further increase orthogonality and usability of dynamic-memory allocation. 8266 This interface helps programmers in three ways. 8267 \begin{enumerate} 8268 \item 8269 naming: \CFA regular and ©ttype© polymorphism (similar to \CC variadic templates) is used to encapsulate a wide range of allocation functionality into a single routine name, so programmers do not have to remember multiple routine names for different kinds of dynamic allocations. 8270 \item 8271 named arguments: individual allocation properties are specified using postfix function call \see{\VRef{s:PostfixFunction}}, so programmers do not have to remember parameter positions in allocation calls. 8272 \item 8273 safe usage: like the \CFA's C-interface, programmers do not have to specify object size or cast allocation results. 8274 \end{enumerate} 8275 8276 The polymorphic functions ©T * alloc( ... )© and ©T * alloc( size_t dim, ... )© are overloaded with a variable number of specific allocation properties, or an integer dimension parameter followed by a variable number of specific allocation properties. 8277 These allocation properties can be passed as named arguments when calling the \lstinline{alloc} routine. 8278 A call without parameters returns an uninitialized dynamically allocated object of type ©T© (©malloc©). 8279 A call with only the dimension (dim) parameter returns an uninitialized dynamically allocated array of objects with type ©T© (©aalloc©). 8280 The variable number of arguments consist of allocation properties, which can be combined to produce different kinds of allocations. 8281 The properties ©resize© and ©realloc© are associated with the allocation variable indicating how the existing allocation is modified, without or with data copying. 8282 Function ©alloc© is used extensively in the \CFA runtime. 8283 8284 The following allocation property functions may be combined and appear in any order as arguments to ©alloc©, 8285 \begin{itemize} 8286 \item 8287 ©T_align ?`align( size_t alignment )© to align an allocation. 8288 The alignment parameter must be $\ge$ the default alignment (©libAlign()© in \CFA) and a power of two, \eg: 8289 \begin{cfa} 8290 int * i0 = alloc( ®4096`align® ); sout | i0 | nl; 8291 int * i1 = alloc( 3, ®4096`align® ); sout | i1; for (i; 3 ) sout | &i1[i] | nonl; sout | nl; 8292 8293 0x555555572000 8294 0x555555574000 0x555555574000 0x555555574004 0x555555574008 8295 \end{cfa} 8296 returns a dynamic object and object array aligned on a 4096-byte boundary. 8297 8298 \item 8299 ©S_fill(T) ?`fill ( /* various types */ )© to initialize storage. 8300 There are three ways to fill storage: 8301 \begin{enumerate} 8302 \item 8303 A ©char© fills every byte of each object. 8304 \item 8305 An object of the returned type fills each object. 8306 \item 8307 An object array pointer fills some or all of the corresponding object array. 8308 \end{enumerate} 8309 For example: 8310 \begin{cfa}[numbers=left] 8311 int * i0 = alloc( ®0n`fill® ); sout | *i0 | nl; // 0n disambiguates 0 8312 int * i1 = alloc( ®5`fill® ); sout | *i1 | nl; 8313 int * i2 = alloc( ®'\xfe'`fill® ); sout | hex( *i2 ) | nl; 8314 int * i3 = alloc( 5, ®5`fill® ); for ( i; 5 ) sout | i3[i] | nonl; sout | nl; 8315 int * i4 = alloc( 5, ®0xdeadbeefN`fill® ); for ( i; 5 ) sout | hex( i4[i] ) | nonl; sout | nl; 8316 int * i5 = alloc( 5, ®i3`fill® ); for ( i; 5 ) sout | i5[i] | nonl; sout | nl; // completely fill from i3 8317 int * i6 = alloc( 5, ®[i3, 3]`fill® ); for ( i; 5 ) sout | i6[i] | nonl; sout | nl; // partial fill from i3 8318 \end{cfa} 8319 \begin{lstlisting}[numbers=left] 8320 0 8321 5 8322 0xfefefefe 8323 5 5 5 5 5 8324 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 8325 5 5 5 5 5 8326 5 5 5 -555819298 -555819298 // two undefined values 8327 \end{lstlisting} 8328 Examples 1 to 3 fill an object with a value or characters. 8329 Examples 4 to 7 fill an array of objects with values, another array, or part of an array. 8330 8331 \item 8332 ©S_resize(T) ?`resize( void * oaddr )© used to resize, realign, and fill, where the old object data is not copied to the new object. 8333 The old object type may be different from the new object type, since the values are not used. 8334 For example: 8335 \begin{cfa}[numbers=left] 8336 int * i = alloc( ®5`fill® ); sout | i | *i; 8337 i = alloc( ®i`resize®, ®256`align®, ®7`fill® ); sout | i | *i; 8338 double * d = alloc( ®i`resize®, ®4096`align®, ®13.5`fill® ); sout | d | *d; 8339 \end{cfa} 8340 \begin{lstlisting}[numbers=left] 8341 0x55555556d5c0 5 8342 0x555555570000 7 8343 0x555555571000 13.5 8344 \end{lstlisting} 8345 Examples 2 to 3 change the alignment, fill, and size for the initial storage of ©i©. 8346 8347 \begin{cfa}[numbers=left] 8348 int * ia = alloc( 5, ®5`fill® ); for ( i; 5 ) sout | ia[i] | nonl; sout | nl; 8349 ia = alloc( 10, ®ia`resize®, ®7`fill® ); for ( i; 10 ) sout | ia[i] | nonl; sout | nl; 8350 sout | ia; ia = alloc( 5, ®ia`resize®, ®512`align®, ®13`fill® ); sout | ia; for ( i; 5 ) sout | ia[i] | nonl; sout | nl;; 8351 ia = alloc( 3, ®ia`resize®, ®4096`align®, ®2`fill® ); sout | ia; for ( i; 3 ) sout | &ia[i] | ia[i] | nonl; sout | nl; 8352 \end{cfa} 8353 \begin{lstlisting}[numbers=left] 8354 5 5 5 5 5 8355 7 7 7 7 7 7 7 7 7 7 8356 0x55555556d560 0x555555571a00 13 13 13 13 13 8357 0x555555572000 0x555555572000 2 0x555555572004 2 0x555555572008 2 8358 \end{lstlisting} 8359 Examples 2 to 4 change the array size, alignment and fill for the initial storage of ©ia©. 8360 8361 \item 8362 ©S_realloc(T) ?`realloc( T * a ))© 8363 used to resize, realign, and fill, where the old object data is copied to the new object. 8364 The old object type must be the same as the new object type, since the value is used. 8365 Note, for ©fill©, only the extra space after copying the data from the old object is filled with the given parameter. 8366 For example: 8367 \begin{cfa}[numbers=left] 8368 int * i = alloc( ®5`fill® ); sout | i | *i; 8369 i = alloc( ®i`realloc®, ®256`align® ); sout | i | *i; 8370 i = alloc( ®i`realloc®, ®4096`align®, ®13`fill® ); sout | i | *i; 8371 \end{cfa} 8372 \begin{lstlisting}[numbers=left] 8373 0x55555556d5c0 5 8374 0x555555570000 5 8375 0x555555571000 5 8376 \end{lstlisting} 8377 Examples 2 to 3 change the alignment for the initial storage of ©i©. 8378 The ©13`fill© in example 3 does nothing because no extra space is added. 8379 8380 \begin{cfa}[numbers=left] 8381 int * ia = alloc( 5, ®5`fill® ); for ( i; 5 ) sout | ia[i]; sout | nl; 8382 ia = alloc( 10, ®ia`realloc®, ®7`fill® ); for ( i; 10 ) sout | ia[i]; sout | nl; 8383 sout | ia; ia = alloc( 1, ®ia`realloc®, ®512`align®, ®13`fill® ); sout | ia; for ( i; 1 ) sout | ia[i]; sout | nl;; 8384 ia = alloc( 3, ®ia`realloc®, ®4096`align®, ®2`fill® ); sout | ia; for ( i; 3 ) sout | &ia[i] | ia[i]; sout | nl; 8385 \end{cfa} 8386 \begin{lstlisting}[numbers=left] 8387 5 5 5 5 5 8388 5 5 5 5 5 7 7 7 7 7 8389 0x55555556c560 0x555555570a00 5 8390 0x555555571000 0x555555571000 5 0x555555571004 2 0x555555571008 2 8391 \end{lstlisting} 8392 Examples 2 to 4 change the array size, alignment and fill for the initial storage of ©ia©. 8393 The ©13`fill© in example 3 does nothing because no extra space is added. 8394 \end{itemize} 8395 8396 \medskip 8086 8397 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8087 8398 extern "C" { 8088 // C unsafe allocation 8089 void * malloc( size_t size );§\indexc{malloc}§ 8090 void * calloc( size_t dim, size_t size );§\indexc{calloc}§ 8091 void * realloc( void * ptr, size_t size );§\indexc{realloc}§ 8092 void * memalign( size_t align, size_t size );§\indexc{memalign}§ 8093 void * aligned_alloc( size_t align, size_t size );§\indexc{aligned_alloc}§ 8094 int posix_memalign( void ** ptr, size_t align, size_t size );§\indexc{posix_memalign}§ 8095 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize );§\indexc{cmemalign}§ // CFA 8096 8097 // C unsafe initialization/copy 8098 void * memset( void * dest, int c, size_t size );§\indexc{memset}§ 8099 void * memcpy( void * dest, const void * src, size_t size );§\indexc{memcpy}§ 8100 } 8101 8102 void * realloc( void * oaddr, size_t nalign, size_t size ); // CFA heap 8103 8104 forall( dtype T | sized(T) ) { 8105 // §\CFA§ safe equivalents, i.e., implicit size specification 8106 T * malloc( void ); 8107 T * calloc( size_t dim ); 8108 T * realloc( T * ptr, size_t size ); 8109 T * memalign( size_t align ); 8110 T * cmemalign( size_t align, size_t dim ); 8111 T * aligned_alloc( size_t align ); 8112 int posix_memalign( T ** ptr, size_t align ); 8399 // New allocation operations. 8400 void * aalloc( size_t dim, size_t elemSize );§\indexc{aalloc}§ 8401 void * resize( void * oaddr, size_t size );§\indexc{resize}§ 8402 void * amemalign( size_t align, size_t dim, size_t elemSize );§\indexc{amemalign}§ 8403 void * cmemalign( size_t align, size_t dim, size_t elemSize );§\indexc{cmemalign}§ 8404 size_t malloc_alignment( void * addr );§\indexc{malloc_alignment}§ 8405 bool malloc_zero_fill( void * addr );§\indexc{malloc_zero_fill}§ 8406 size_t malloc_size( void * addr );§\indexc{malloc_size}§ 8407 int malloc_stats_fd( int fd );§\indexc{malloc_stats_fd}§ 8408 size_t malloc_expansion();§\indexc{malloc_expansion}§ $\C{// heap expansion size (bytes)}$ 8409 size_t malloc_mmap_start();§\indexc{malloc_mmap_start}§ $\C{// crossover allocation size from sbrk to mmap}$ 8410 size_t malloc_unfreed();§\indexc{malloc_unfreed()}§ $\C{// heap unfreed size (bytes)}$ 8411 void malloc_stats_clear();§\indexc{malloc_stats_clear}§ $\C{// clear heap statistics}$ 8412 } 8413 8414 // New allocation operations. 8415 void * resize( void * oaddr, size_t alignment, size_t size ); 8416 void * realloc( void * oaddr, size_t alignment, size_t size ); 8417 void * reallocarray( void * oaddr, size_t nalign, size_t dim, size_t elemSize ); 8418 8419 forall( T & | sized(T) ) { 8420 // §\CFA§ safe equivalents, i.e., implicit size specification, eliminate return-type cast 8421 T * malloc( void );§\indexc{malloc}§ 8422 T * aalloc( size_t dim );§\indexc{aalloc}§ 8423 T * calloc( size_t dim );§\indexc{calloc}§ 8424 T * resize( T * ptr, size_t size );§\indexc{resize}§ 8425 T * realloc( T * ptr, size_t size );§\indexc{realloc}§ 8426 T * reallocarray( T * ptr, size_t dim );§\indexc{reallocarray}§ 8427 T * memalign( size_t align );§\indexc{memalign}§ 8428 T * amemalign( size_t align, size_t dim );§\indexc{amemalign}§ 8429 T * cmemalign( size_t align, size_t dim );§\indexc{aalloc}§ 8430 T * aligned_alloc( size_t align );§\indexc{aligned_alloc}§ 8431 int posix_memalign( T ** ptr, size_t align );§\indexc{posix_memalign}§ 8432 T * valloc( void );§\indexc{valloc}§ 8433 T * pvalloc( void );§\indexc{pvalloc}§ 8113 8434 8114 8435 // §\CFA§ safe general allocation, fill, resize, alignment, array 8115 T * alloc( void );§\indexc{alloc}§ §\C[3.5in]{// variable, T size}§ 8116 T * alloc( size_t dim ); §\C{// array[dim], T size elements}§ 8117 T * alloc( T ptr[], size_t dim ); §\C{// realloc array[dim], T size elements}§ 8118 8119 T * alloc_set( char fill );§\indexc{alloc_set}§ §\C{// variable, T size, fill bytes with value}§ 8120 T * alloc_set( T fill ); §\C{// variable, T size, fill with value}§ 8121 T * alloc_set( size_t dim, char fill ); §\C{// array[dim], T size elements, fill bytes with value}§ 8122 T * alloc_set( size_t dim, T fill ); §\C{// array[dim], T size elements, fill elements with value}§ 8123 T * alloc_set( size_t dim, const T fill[] ); §\C{// array[dim], T size elements, fill elements with array}§ 8124 T * alloc_set( T ptr[], size_t dim, char fill ); §\C{// realloc array[dim], T size elements, fill bytes with value}§ 8125 8126 T * alloc_align( size_t align ); §\C{// aligned variable, T size}§ 8127 T * alloc_align( size_t align, size_t dim ); §\C{// aligned array[dim], T size elements}§ 8128 T * alloc_align( T ptr[], size_t align ); §\C{// realloc new aligned array}§ 8129 T * alloc_align( T ptr[], size_t align, size_t dim ); §\C{// realloc new aligned array[dim]}§ 8130 8131 T * alloc_align_set( size_t align, char fill ); §\C{// aligned variable, T size, fill bytes with value}§ 8132 T * alloc_align_set( size_t align, T fill ); §\C{// aligned variable, T size, fill with value}§ 8133 T * alloc_align_set( size_t align, size_t dim, char fill ); §\C{// aligned array[dim], T size elements, fill bytes with value}§ 8134 T * alloc_align_set( size_t align, size_t dim, T fill ); §\C{// aligned array[dim], T size elements, fill elements with value}§ 8135 T * alloc_align_set( size_t align, size_t dim, const T fill[] ); §\C{// aligned array[dim], T size elements, fill elements with array}§ 8136 T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); §\C{// realloc new aligned array[dim], fill new bytes with value}§ 8436 T * alloc( ... );§\indexc{alloc}§ §\C{// variable, T size}§ 8437 T * alloc( size_t dim, ... ); 8438 T_align ?`align( size_t alignment );§\indexc{align}§ 8439 S_fill(T) ?`fill( /* various types */ );§\indexc{fill}§ 8440 S_resize(T) ?`resize( void * oaddr );§\indexc{resize}§ 8441 S_realloc(T) ?`realloc( T * a ));§\indexc{realloc}§ 8137 8442 8138 8443 // §\CFA§ safe initialization/copy, i.e., implicit size specification … … 8146 8451 8147 8452 // §\CFA§ allocation/deallocation and constructor/destructor, non-array types 8148 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );§\indexc{new}§ 8149 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr );§\indexc{delete}§ 8150 forall( dtype T, ttype Params | sized(T) | { void ^?{}( T & ); void delete( Params ); } ) 8151 void delete( T * ptr, Params rest ); 8453 forall( T &, TT ... ) void free( T * ptr, ... ); 8454 8455 forall( T & | sized(T), Params ... | { void ?{}( T &, Params ); } ) 8456 T * new( Params p );§\indexc{new}§ 8457 forall( T & | { void ^?{}( T & ); } ) 8458 void delete( T * ptr );§\indexc{delete}§ 8459 forall( T &, Params ... | { void ^?{}( T & ); void delete( Params ); } ) 8460 void delete( T * ptr, Params rest ); 8152 8461 8153 8462 // §\CFA§ allocation/deallocation and constructor/destructor, array types 8154 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );§\indexc{anew}§ 8155 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] );§\indexc{adelete}§ 8156 forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } ) 8157 void adelete( size_t dim, T arr[], Params rest ); 8463 forall( T & | sized(T), Params ... | { void ?{}( T &, Params ); } ) 8464 T * anew( size_t dim, Params p );§\indexc{anew}§ 8465 forall( T & | sized(T) | { void ^?{}( T & ); } ) 8466 void adelete( T arr[] );§\indexc{adelete}§ 8467 forall( T & | sized(T) | { void ^?{}( T & ); }, Params ... | { void adelete( Params ); } ) 8468 void adelete( T arr[], Params rest ); 8158 8469 \end{cfa} 8159 8470 … … 9290 9601 Int sqrt( Int oper ); 9291 9602 9292 forall( dtype istype| istream( istype ) ) istype * ?|?( istype * is, Int * mp ); §\C{// I/O}§9293 forall( dtype ostype| ostream( ostype ) ) ostype * ?|?( ostype * os, Int mp );9603 forall( istype & | istream( istype ) ) istype * ?|?( istype * is, Int * mp ); §\C{// I/O}§ 9604 forall( ostype & | ostream( ostype ) ) ostype * ?|?( ostype * os, Int mp ); 9294 9605 \end{cfa} 9295 9606 \VRef[Figure]{f:MultiPrecisionFactorials} shows \CFA and C factorial programs using the GMP interfaces. … … 9299 9610 \begin{cquote} 9300 9611 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 9301 \multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{ C}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c@{}}{\textbf{\CFA}} \\9612 \multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c@{}}{\textbf{C}} \\ 9302 9613 \hline 9614 \begin{cfa} 9615 #include <gmp.hfa>§\indexc{gmp}§ 9616 int main( void ) { 9617 sout | "Factorial Numbers"; 9618 ®Int® fact = 1; 9619 9620 sout | 0 | fact; 9621 for ( i; 40 ) { 9622 fact *= i; 9623 sout | i | fact; 9624 } 9625 } 9626 \end{cfa} 9627 & 9303 9628 \begin{cfa} 9304 9629 #include <gmp.h>§\indexc{gmp.h}§ … … 9311 9636 ®mpz_mul_ui®( fact, fact, i ); 9312 9637 ®gmp_printf®( "%d %Zd\n", i, fact ); 9313 }9314 }9315 \end{cfa}9316 &9317 \begin{cfa}9318 #include <gmp.hfa>§\indexc{gmp}§9319 int main( void ) {9320 sout | "Factorial Numbers";9321 Int fact = 1;9322 9323 sout | 0 | fact;9324 for ( i; 40 ) {9325 fact *= i;9326 sout | i | fact;9327 9638 } 9328 9639 } … … 9419 9730 Rational narrow( double f, long int md ); 9420 9731 9421 forall( dtype istype| istream( istype ) ) istype * ?|?( istype *, Rational * ); // I/O9422 forall( dtype ostype| ostream( ostype ) ) ostype * ?|?( ostype *, Rational );9732 forall( istype & | istream( istype ) ) istype * ?|?( istype *, Rational * ); // I/O 9733 forall( ostype & | ostream( ostype ) ) ostype * ?|?( ostype *, Rational ); 9423 9734 \end{cfa} 9424 9735 … … 9440 9751 \end{document} 9441 9752 9753 From: Michael Leslie Brooks <mlbrooks@uwaterloo.ca> 9754 To: Peter Buhr <pabuhr@uwaterloo.ca>, 9755 Andrew James Beach 9756 <ajbeach@uwaterloo.ca>, 9757 Fangren Yu <f37yu@uwaterloo.ca>, Jiada Liang 9758 <j82liang@uwaterloo.ca> 9759 Subject: The White House on Memory-Safe programming 9760 Date: Mon, 4 Mar 2024 16:49:53 +0000 9761 9762 I heard tell of this announcement last night. Haven't read the actual report yet. 9763 9764 Most mainstream article I can find: https://me.pcmag.com/en/security/22413/white-house-to-developers-using-c-or-c-invites-cybersecurity-risks 9765 Less fluffy summary: https://www.developer-tech.com/news/2024/feb/27/white-house-urges-adoption-memory-safe-programming-languages/ 9766 Horse's Mouth: https://www.whitehouse.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf 9767 "This report focuses on the programming language as a primary building block, and explores hardware architecture and formal methods as complementary approaches" 9768 9769 A contrary analysis: https://hackaday.com/2024/02/29/the-white-house-memory-safety-appeal-is-a-security-red-herring/ 9770 9442 9771 % Local Variables: % 9443 9772 % tab-width: 4 % -
libcfa/src/concurrency/actor.hfa
r02c80cdc r4e08a54 299 299 300 300 if ( seperate_clus ) { 301 cluster = alloc();301 this.cluster = alloc(); 302 302 (*cluster){}; 303 303 } else cluster = active_cluster(); … … 360 360 adelete( worker_req_queues ); 361 361 adelete( processors ); 362 if ( seperate_clus ) delete( cluster );362 if ( seperate_clus ) delete( this.cluster ); 363 363 364 364 #ifdef ACTOR_STATS // print formatted stats
Note:
See TracChangeset
for help on using the changeset viewer.