Changeset caa649b for doc/papers


Ignore:
Timestamp:
Mar 6, 2018, 12:11:11 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
520145b, e5d4e5c, e6c5e79
Parents:
094476d (diff), 1feb535f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
doc/papers/general
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • doc/papers/general/Paper.tex

    r094476d rcaa649b  
    1313\usepackage{pslatex}                                            % reduce size of san serif font
    1414\usepackage[plainpages=false,pdfpagelabels,pdfpagemode=UseNone,pagebackref=true,breaklinks=true,colorlinks=true,linkcolor=blue,citecolor=blue,urlcolor=blue]{hyperref}
     15\urlstyle{sf}
     16\usepackage{breakurl}
    1517
    1618\setlength{\textheight}{9in}
     
    199201The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from commercial operating-systems to hobby projects.
    200202This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more.
    201 The TIOBE~\cite{TIOBE} ranks the top 5 most popular programming languages as: Java 16\%, \Textbf{C 7\%}, \Textbf{\CC 5\%}, \Csharp 4\%, Python 4\% = 36\%, where the next 50 languages are less than 3\% each with a long tail.
     203The TIOBE~\cite{TIOBE} ranks the top 5 most \emph{popular} programming languages as: Java 15\%, \Textbf{C 12\%}, \Textbf{\CC 5.5\%}, Python 5\%, \Csharp 4.5\% = 42\%, where the next 50 languages are less than 4\% each with a long tail.
    202204The top 3 rankings over the past 30 years are:
    203205\begin{center}
     
    205207\lstDeleteShortInline@%
    206208\begin{tabular}{@{}rccccccc@{}}
    207                 & 2017  & 2012  & 2007  & 2002  & 1997  & 1992  & 1987          \\ \hline
    208 Java    & 1             & 1             & 1             & 1             & 12    & -             & -                     \\
    209 \Textbf{C}      & \Textbf{2}& \Textbf{2}& \Textbf{2}& \Textbf{2}& \Textbf{1}& \Textbf{1}& \Textbf{1}    \\
    210 \CC             & 3             & 3             & 3             & 3             & 2             & 2             & 4                     \\
     209                & 2018  & 2013  & 2008  & 2003  & 1998  & 1993  & 1988  \\ \hline
     210Java    & 1             & 2             & 1             & 1             & 18    & -             & -             \\
     211\Textbf{C}& \Textbf{2} & \Textbf{1} & \Textbf{2} & \Textbf{2} & \Textbf{1} & \Textbf{1} & \Textbf{1} \\
     212\CC             & 3             & 4             & 3             & 3             & 2             & 2             & 5             \\
    211213\end{tabular}
    212214\lstMakeShortInline@%
     
    227229\CFA is currently implemented as a source-to-source translator from \CFA to the gcc-dialect of C~\cite{GCCExtensions}, allowing it to leverage the portability and code optimizations provided by gcc, meeting goals (1)--(3).
    228230Ultimately, a compiler is necessary for advanced features and optimal performance.
    229 
    230 This paper identifies shortcomings in existing approaches to generic and variadic data types in C-like languages and presents a design for generic and variadic types avoiding those shortcomings.
     231All of the features discussed in this paper are working, unless a feature states it is a future feature for completion.
     232
     233
     234\section{Polymorphic Functions}
     235
     236\CFA introduces both ad-hoc and parametric polymorphism to C, with a design originally formalized by Ditchfield~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}.
     237Shortcomings are identified in existing approaches to generic and variadic data types in C-like languages and how these shortcomings are avoided in \CFA.
    231238Specifically, the solution is both reusable and type-checked, as well as conforming to the design goals of \CFA with ergonomic use of existing C abstractions.
    232 The new constructs are empirically compared with both standard C and \CC; the results show the new design is comparable in performance.
    233 
    234 \section{Polymorphic Functions}
    235 
    236 \CFA introduces both ad-hoc and parametric polymorphism to C, with a design originally formalized by Ditchfield~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}.
     239The new constructs are empirically compared with C and \CC approaches via performance experiments in Section~\ref{sec:eval}.
     240
    237241
    238242\subsection{Name Overloading}
    239 
     243\label{s:NameOverloading}
     244
     245\begin{quote}
     246There are only two hard things in Computer Science: cache invalidation and \emph{naming things} -- Phil Karlton
     247\end{quote}
    240248C already has a limited form of ad-hoc polymorphism in the form of its basic arithmetic operators, which apply to a variety of different types using identical syntax.
    241249\CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable;
     
    245253
    246254\begin{cfa}
    247 int max(int a, int b) { return a < b ? b : a; }  // (1)
    248 double max(double a, double b) { return a < b ? b : a; }  // (2)
    249 
    250 int max = INT_MAX;     // (3)
    251 double max = DBL_MAX;  // (4)
    252 
    253 max(7, -max);   $\C{// uses (1) and (3), by matching int from constant 7}$
    254 max(max, 3.14); $\C{// uses (2) and (4), by matching double from constant 3.14}$
    255 
    256 //max(max, -max);  $\C{// ERROR: ambiguous}$
    257 int m = max(max, -max); $\C{// uses (1) once and (3) twice, by matching return type}$
    258 \end{cfa}
    259 
    260 \Celeven did add @_Generic@ expressions, which can be used in preprocessor macros to provide a form of ad-hoc polymorphism; however, this polymorphism is both functionally and ergonomically inferior to \CFA name overloading.
     255int max = 2147483647;                                           $\C[3.75in]{// (1)}$
     256double max = 1.7976931348623157E+308;   $\C{// (2)}$
     257int max( int a, int b ) { return a < b ? b : a; }  $\C{// (3)}$
     258double max( double a, double b ) { return a < b ? b : a; }  $\C{// (4)}\CRT$
     259max( 7, -max );                                                         $\C{// uses (3) and (1), by matching int from constant 7}$
     260max( max, 3.14 );                                                       $\C{// uses (4) and (2), by matching double from constant 3.14}$
     261max( max, -max );                                                       $\C{// ERROR: ambiguous}$
     262int m = max( max, -max );                                       $\C{// uses (3) and (1) twice, by matching return type}$
     263\end{cfa}
     264\CFA maximizes the ability to reuse names to aggressively address the naming problem.
     265In some cases, hundreds of names can be reduced to tens, resulting in a significant cognitive reduction for a programmer.
     266In the above, the name @max@ has a consistent meaning, and a programmer only needs to remember the single concept: maximum.
     267To prevent significant ambiguities, \CFA uses the return type in selecting overloads, \eg in the assignment to @m@, the compiler use @m@'s type to unambiguously select the most appropriate call to function @max@ (as does Ada).
     268As is shown later, there are a number of situations where \CFA takes advantage of available type information to disambiguate, where other programming languages generate ambiguities.
     269
     270\Celeven added @_Generic@ expressions, which can be used in preprocessor macros to provide a form of ad-hoc polymorphism; however, this polymorphism is both functionally and ergonomically inferior to \CFA name overloading.
    261271The macro wrapping the generic expression imposes some limitations; as an example, it could not implement the example above, because the variables @max@ would collide with the functions @max@.
    262272Ergonomic limitations of @_Generic@ include the necessity to put a fixed list of supported types in a single place and manually dispatch to appropriate overloads, as well as possible namespace pollution from the functions dispatched to, which must all have distinct names.
    263 Though name-overloading removes a major use-case for @_Generic@ expressions, \CFA does implement @_Generic@ for backwards-compatibility purposes. \TODO{actually implement that}
     273Though name-overloading removes a major use-case for @_Generic@ expressions, \CFA implements @_Generic@ for backwards-compatibility purposes. \TODO{actually implement that}
    264274
    265275% http://fanf.livejournal.com/144696.html
     
    288298For example, the function @twice@ can be defined using the \CFA syntax for operator overloading:
    289299\begin{cfa}
    290 forall( otype T `| { T ?+?(T, T); }` ) T twice( T x ) { return x + x; } $\C{// ? denotes operands}$
     300forall( otype T `| { T ?+?(T, T); }` ) T twice( T x ) { return x `+` x; }       $\C{// ? denotes operands}$
    291301int val = twice( twice( 3.7 ) );
    292302\end{cfa}
     
    343353\begin{cfa}
    344354forall( otype T | { int ?<?( T, T ); } ) void qsort( const T * arr, size_t size ) { /* use C qsort */ }
    345 {       int ?<?( double x, double y ) { return x `>` y; }       $\C{// locally override behaviour}$
     355{
     356        int ?<?( double x, double y ) { return x `>` y; }       $\C{// locally override behaviour}$
    346357        qsort( vals, size );                                    $\C{// descending sort}$
    347358}
     
    414425\section{Generic Types}
    415426
    416 One of the known shortcomings of standard C is that it does not provide reusable type-safe abstractions for generic data structures and algorithms.
     427A significant shortcoming of standard C is the lack of reusable type-safe abstractions for generic data structures and algorithms.
    417428Broadly speaking, there are three approaches to implement abstract data-structures in C.
    418429One approach is to write bespoke data-structures for each context in which they are needed.
    419430While this approach is flexible and supports integration with the C type-checker and tooling, it is also tedious and error-prone, especially for more complex data structures.
    420 A second approach is to use @void *@--based polymorphism, \eg the C standard-library functions @bsearch@ and @qsort@; an approach which does allow reuse of code for common functionality.
    421 However, basing all polymorphism on @void *@ eliminates the type-checker's ability to ensure that argument types are properly matched, often requiring a number of extra function parameters, pointer indirection, and dynamic allocation that would not otherwise be needed.
     431A second approach is to use @void *@--based polymorphism, \eg the C standard-library functions @bsearch@ and @qsort@, which allows reuse of code with common functionality.
     432However, basing all polymorphism on @void *@ eliminates the type-checker's ability to ensure that argument types are properly matched, often requiring a number of extra function parameters, pointer indirection, and dynamic allocation that is not otherwise needed.
    422433A third approach to generic code is to use preprocessor macros, which does allow the generated code to be both generic and type-checked, but errors may be difficult to interpret.
    423434Furthermore, writing and using preprocessor macros can be unnatural and inflexible.
     
    434445};
    435446forall( otype T ) T value( pair( const char *, T ) p ) { return p.second; }
    436 forall( dtype F, otype T ) T value_p( pair( F *, T * ) p ) { return * p.second; }
     447forall( dtype F, otype T ) T value( pair( F *, T * ) p ) { return *p.second; }
    437448
    438449pair( const char *, int ) p = { "magic", 42 };
    439 int magic = value( p );
     450int i = value( p );
    440451pair( void *, int * ) q = { 0, &p.second };
    441 magic = value_p( q );
     452i = value( q );
    442453double d = 1.0;
    443454pair( double *, double * ) r = { &d, &d };
    444 d = value_p( r );
     455d = value( r );
    445456\end{cfa}
    446457
     
    589600[ double ] foo$\(_2\)$( int );
    590601void bar( int, double, double );
    591 bar( foo( 3 ), foo( 3 ) );
     602`bar`( foo( 3 ), foo( 3 ) );
    592603\end{cfa}
    593604The type-resolver only has the tuple return-types to resolve the call to @bar@ as the @foo@ parameters are identical, which involves unifying the possible @foo@ functions with @bar@'s parameter list.
     
    835846Since @sum@\(_0\) does not accept any arguments, it is not a valid candidate function for the call @sum(10, 20, 30)@.
    836847In order to call @sum@\(_1\), @10@ is matched with @x@, and the argument resolution moves on to the argument pack @rest@, which consumes the remainder of the argument list and @Params@ is bound to @[20, 30]@.
    837 The process continues unitl @Params@ is bound to @[]@, requiring an assertion @int sum()@, which matches @sum@\(_0\) and terminates the recursion.
     848The process continues until @Params@ is bound to @[]@, requiring an assertion @int sum()@, which matches @sum@\(_0\) and terminates the recursion.
    838849Effectively, this algorithm traces as @sum(10, 20, 30)@ $\rightarrow$ @10 + sum(20, 30)@ $\rightarrow$ @10 + (20 + sum(30))@ $\rightarrow$ @10 + (20 + (30 + sum()))@ $\rightarrow$ @10 + (20 + (30 + 0))@.
    839850
     
    979990\section{Control Structures}
    980991
    981 \CFA identifies missing and problematic control structures in C, and extends and modifies these control structures to increase functionality and safety.
     992\CFA identifies inconsistent, problematic, and missing control structures in C, and extends, modifies, and adds to control structures to increase functionality and safety.
     993
     994
     995\subsection{\texorpdfstring{\LstKeywordStyle{if} Statement}{if Statement}}
     996
     997The @if@ expression allows declarations, similar to @for@ declaration expression:
     998\begin{cfa}
     999if ( int x = f() ) ...                                          $\C{// x != 0}$
     1000if ( int x = f(), y = g() ) ...                         $\C{// x != 0 \&\& y != 0}$
     1001if ( int x = f(), y = g(); `x < y` ) ...        $\C{// relational expression}$
     1002\end{cfa}
     1003Unless a relational expression is specified, each variable is compared not equal to 0, which is the standard semantics for the @if@ expression, and the results are combined using the logical @&&@ operator.\footnote{\CC only provides a single declaration always compared not equal to 0.}
     1004The scope of the declaration(s) is local to the @if@ statement but exist within both the ``then'' and ``else'' clauses.
     1005
     1006
     1007\subsection{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}}
     1008
     1009There are a number of deficiencies with the C @switch@ statements: enumerating @case@ lists, placement of @case@ clauses, scope of the switch body, and fall through between case clauses.
     1010
     1011C has no shorthand for specifying a list of case values, whether the list is non-contiguous or contiguous\footnote{C provides this mechanism via fall through.}.
     1012\CFA provides a shorthand for a non-contiguous list:
     1013\begin{cquote}
     1014\lstDeleteShortInline@%
     1015\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
     1016\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
     1017\begin{cfa}
     1018case 2, 10, 34, 42:
     1019\end{cfa}
     1020&
     1021\begin{cfa}
     1022case 2: case 10: case 34: case 42:
     1023\end{cfa}
     1024\end{tabular}
     1025\lstMakeShortInline@%
     1026\end{cquote}
     1027for a contiguous list:\footnote{gcc provides the same mechanism with awkward syntax, \lstinline@2 ... 42@, where spaces are required around the ellipse.}
     1028\begin{cquote}
     1029\lstDeleteShortInline@%
     1030\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
     1031\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
     1032\begin{cfa}
     1033case 2~42:
     1034\end{cfa}
     1035&
     1036\begin{cfa}
     1037case 2: case 3: ... case 41: case 42:
     1038\end{cfa}
     1039\end{tabular}
     1040\lstMakeShortInline@%
     1041\end{cquote}
     1042and a combination:
     1043\begin{cfa}
     1044case -12~-4, -1~5, 14~21, 34~42:
     1045\end{cfa}
     1046
     1047C allows placement of @case@ clauses \emph{within} statements nested in the @switch@ body (see Duff's device~\cite{Duff83});
     1048\begin{cfa}
     1049switch ( i ) {
     1050  case 0:
     1051        for ( int i = 0; i < 10; i += 1 ) {
     1052                ...
     1053  `case 1:`             // no initialization of loop index
     1054                ...
     1055        }
     1056}
     1057\end{cfa}
     1058\CFA precludes this form of transfer into a control structure because it causes undefined behaviour, especially with respect to missed initialization, and provides very limited functionality.
     1059
     1060C allows placement of declaration within the @switch@ body and unreachable code at the start, resulting in undefined behaviour:
     1061\begin{cfa}
     1062switch ( x ) {
     1063        `int y = 1;`                                                    $\C{// unreachable initialization}$
     1064        `x = 7;`                                                                $\C{// unreachable code without label/branch}$
     1065  case 0:
     1066        ...
     1067        `int z = 0;`                                                    $\C{// unreachable initialization, cannot appear after case}$
     1068        z = 2;
     1069  case 1:
     1070        `x = z;`                                                                $\C{// without fall through, z is undefined}$
     1071}
     1072\end{cfa}
     1073\CFA allows the declaration of local variables, \eg @y@, at the start of the @switch@ with scope across the entire @switch@ body, \ie all @case@ clauses.
     1074\CFA disallows the declaration of local variable, \eg @z@, directly within the @switch@ body, because a declaration cannot occur immediately after a @case@ since a label can only be attached to a statement, and the use of @z@ is undefined in @case 1@ as neither storage allocation nor initialization may have occurred.
     1075
     1076C @switch@ provides multiple entry points into the statement body, but once an entry point is selected, control continues across \emph{all} @case@ clauses until the end of the @switch@ body, called \newterm{fall through};
     1077@case@ clauses are made disjoint by the @break@ statement.
     1078While the ability to fall through \emph{is} a useful form of control flow, it does not match well with programmer intuition, resulting in many errors from missing @break@ statements.
     1079For backwards compatibility, \CFA provides a \emph{new} control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through (see Figure~\ref{f:ChooseSwitchStatements}).
     1080Collectively, these enhancements reduce programmer burden and increase readability and safety.
     1081
     1082\begin{figure}
     1083\centering
     1084\lstDeleteShortInline@%
     1085\begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
     1086\multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}}    & \multicolumn{1}{c}{\textbf{C}}        \\
     1087\begin{cfa}
     1088`choose` ( day ) {
     1089  case Mon~Thu:  // program
     1090
     1091  case Fri:  // program
     1092        wallet += pay;
     1093        `fallthrough;`
     1094  case Sat:  // party
     1095        wallet -= party;
     1096
     1097  case Sun:  // rest
     1098
     1099  default:  // error
     1100}
     1101\end{cfa}
     1102&
     1103\begin{cfa}
     1104switch ( day ) {
     1105  case Mon: case Tue: case Wed: case Thu:  // program
     1106        `break;`
     1107  case Fri:  // program
     1108        wallet += pay;
     1109
     1110  case Sat:  // party
     1111        wallet -= party;
     1112        `break;`
     1113  case Sun:  // rest
     1114        `break;`
     1115  default:  // error
     1116}
     1117\end{cfa}
     1118\end{tabular}
     1119\lstMakeShortInline@%
     1120\caption{\lstinline|choose| versus \lstinline|switch| Statements}
     1121\label{f:ChooseSwitchStatements}
     1122\end{figure}
     1123
     1124\begin{comment}
     1125Forgotten @break@ statements at the end of @switch@ cases are a persistent sort of programmer error in C, and the @break@ statements themselves introduce visual clutter and an un-C-like keyword-based block delimiter.
     1126\CFA addresses this error by introducing a @choose@ statement, which works identically to a @switch@ except that its default end-of-case behaviour is to break rather than to fall through for all non-empty cases.
     1127Since empty cases like @case 7:@ in @case 7: case 11:@ still have fall-through semantics and explicit @break@ is still allowed at the end of a @choose@ case, many idiomatic uses of @switch@ in standard C can be converted to @choose@ statements by simply changing the keyword.
     1128Where fall-through is desired for a non-empty case, it can be specified with the new @fallthrough@ statement, making @choose@ equivalently powerful to @switch@, but more concise in the common case where most non-empty cases end with a @break@ statement, as in the example below:
     1129
     1130\begin{cfa}
     1131choose( i ) {
     1132        case 2:
     1133                printf("even ");
     1134                fallthrough;
     1135        case 3: case 5: case 7:
     1136                printf("small prime\n");
     1137        case 4,6,8,9:
     1138                printf("small composite\n");
     1139        case 13~19:
     1140                printf("teen\n");
     1141        default:
     1142                printf("something else\n");
     1143}
     1144\end{cfa}
     1145\end{comment}
    9821146
    9831147
     
    10391203                } else {
    10401204                        ... goto `LIF`; ...
    1041                 } `L3:` ;
     1205                } `LIF:` ;
    10421206        } `LS:` ;
    10431207} `LC:` ;
     
    10891253
    10901254
    1091 \subsection{\texorpdfstring{Enhanced \LstKeywordStyle{switch} Statement}{Enhanced switch Statement}}
    1092 
    1093 There are a number of deficiencies with the C @switch@ statements: enumerating @case@ lists, placement of @case@ clauses, scope of the switch body, and fall through between case clauses.
    1094 
    1095 C has no shorthand for specifying a list of case values, whether the list is non-contiguous or contiguous\footnote{C provides this mechanism via fall through.}.
    1096 \CFA provides a shorthand for a non-contiguous list:
     1255\subsection{Exception Handling}
     1256
     1257The following framework for \CFA exception handling is in place, excluding a run-time type information and dynamic casts.
     1258\CFA provides two forms of exception handling: \newterm{fix-up} and \newterm{recovery} (see Figure~\ref{f:CFAExceptionHandling}).
     1259Both mechanisms provide dynamic call to a handler using dynamic name-lookup, where fix-up has dynamic return and recovery has static return from the handler.
     1260\CFA restricts exception types to those defined by aggregate type @exception@.
     1261The form of the raise dictates the set of handlers examined during propagation: \newterm{resumption propagation} (@resume@) only examines resumption handlers (@catchResume@); \newterm{terminating propagation} (@throw@) only examines termination handlers (@catch@).
     1262If @resume@ or @throw@ have no exception type, it is a reresume/rethrow, meaning the currently exception continues propagation.
     1263If there is no current exception, the reresume/rethrow results in a runtime error.
     1264
     1265\begin{figure}
    10971266\begin{cquote}
    10981267\lstDeleteShortInline@%
    1099 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    1100 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    1101 \begin{cfa}
    1102 case 2, 10, 34, 42:
    1103 \end{cfa}
    1104 &
    1105 \begin{cfa}
    1106 case 2: case 10: case 34: case 42:
     1268\begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
     1269\multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{Resumption}}      & \multicolumn{1}{c}{\textbf{Termination}}      \\
     1270\begin{cfa}
     1271`exception R { int fix; };`
     1272void f() {
     1273        R r;
     1274        ... `resume( r );` ...
     1275        ... r.fix // control does return here after handler
     1276}
     1277`try` {
     1278        ... f(); ...
     1279} `catchResume( R r )` {
     1280        ... r.fix = ...; // return correction to raise
     1281} // dynamic return to _Resume
     1282\end{cfa}
     1283&
     1284\begin{cfa}
     1285`exception T {};`
     1286void f() {
     1287
     1288        ... `throw( T{} );` ...
     1289        // control does NOT return here after handler
     1290}
     1291`try` {
     1292        ... f(); ...
     1293} `catch( T t )` {
     1294        ... // recover and continue
     1295} // static return to next statement
    11071296\end{cfa}
    11081297\end{tabular}
    11091298\lstMakeShortInline@%
    11101299\end{cquote}
    1111 for a contiguous list:\footnote{gcc provides the same mechanism with awkward syntax, \lstinline@2 ... 42@, where spaces are required around the ellipse.}
     1300\caption{\CFA Exception Handling}
     1301\label{f:CFAExceptionHandling}
     1302\end{figure}
     1303
     1304The set of exception types in a list of catch clause may include both a resumption and termination handler:
     1305\begin{cfa}
     1306try {
     1307        ... resume( `R{}` ); ...
     1308} catchResume( `R` r ) { ... throw( R{} ); ... } $\C{\color{red}// H1}$
     1309   catch( `R` r ) { ... }                                       $\C{\color{red}// H2}$
     1310
     1311\end{cfa}
     1312The resumption propagation raises @R@ and the stack is not unwound;
     1313the exception is caught by the @catchResume@ clause and handler H1 is invoked.
     1314The termination propagation in handler H1 raises @R@ and the stack is unwound;
     1315the exception is caught by the @catch@ clause and handler H2 is invoked.
     1316The termination handler is available because the resumption propagation did not unwind the stack.
     1317
     1318An additional feature is conditional matching in a catch clause:
     1319\begin{cfa}
     1320try {
     1321        ... write( `datafile`, ... ); ...               $\C{// may throw IOError}$
     1322        ... write( `logfile`, ... ); ...
     1323} catch ( IOError err; `err.file == datafile` ) { ... } $\C{// handle datafile error}$
     1324   catch ( IOError err; `err.file == logfile` ) { ... } $\C{// handle logfile error}$
     1325   catch ( IOError err ) { ... }                        $\C{// handler error from other files}$
     1326\end{cfa}
     1327where the throw inserts the failing file-handle in the I/O exception.
     1328Conditional catch cannot be trivially mimicked by other mechanisms because once an exception is caught, handler clauses in that @try@ statement are no longer eligible..
     1329
     1330The resumption raise can specify an alternate stack on which to raise an exception, called a \newterm{nonlocal raise}:
     1331\begin{cfa}
     1332resume( $\emph{exception-type}$, $\emph{alternate-stack}$ )
     1333resume( $\emph{alternate-stack}$ )
     1334\end{cfa}
     1335These overloads of @resume@ raise the specified exception or the currently propagating exception (reresume) at another coroutine or task~\cite{Delisle18}.
     1336Nonlocal raise is restricted to resumption to provide the exception handler the greatest flexibility because processing the exception does not unwind its stack, allowing it to continue after the handle returns.
     1337
     1338To facilitate nonlocal exception, \CFA provides dynamic enabling and disabling of nonlocal exception-propagation.
     1339The constructs for controlling propagation of nonlocal exceptions are the @enable@ and the @disable@ blocks:
    11121340\begin{cquote}
    11131341\lstDeleteShortInline@%
    1114 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    1115 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    1116 \begin{cfa}
    1117 case 2~42:
    1118 \end{cfa}
    1119 &
    1120 \begin{cfa}
    1121 case 2: case 3: ... case 41: case 42:
     1342\begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
     1343\begin{cfa}
     1344enable $\emph{exception-type-list}$ {
     1345        // allow non-local resumption
     1346}
     1347\end{cfa}
     1348&
     1349\begin{cfa}
     1350disable $\emph{exception-type-list}$ {
     1351        // disallow non-local resumption
     1352}
    11221353\end{cfa}
    11231354\end{tabular}
    11241355\lstMakeShortInline@%
    11251356\end{cquote}
    1126 and a combination:
    1127 \begin{cfa}
    1128 case -12~-4, -1~5, 14~21, 34~42:
    1129 \end{cfa}
    1130 
    1131 C allows placement of @case@ clauses \emph{within} statements nested in the @switch@ body (see Duff's device~\cite{Duff83});
    1132 \begin{cfa}
    1133 switch ( i ) {
    1134   case 0:
    1135         for ( int i = 0; i < 10; i += 1 ) {
    1136                 ...
    1137   `case 1:`             // no initialization of loop index
    1138                 ...
    1139         }
    1140 }
    1141 \end{cfa}
    1142 \CFA precludes this form of transfer into a control structure because it causes undefined behaviour, especially with respect to missed initialization, and provides very limited functionality.
    1143 
    1144 C allows placement of declaration within the @switch@ body and unreachable code at the start, resulting in undefined behaviour:
    1145 \begin{cfa}
    1146 switch ( x ) {
    1147         `int y = 1;`                            $\C{// unreachable initialization}$
    1148         `x = 7;`                                        $\C{// unreachable code without label/branch}$
    1149   case 0:
    1150         ...
    1151         `int z = 0;`                            $\C{// unreachable initialization, cannot appear after case}$
    1152         z = 2;
    1153   case 1:
    1154         `x = z;`                                        $\C{// without fall through, z is undefined}$
    1155 }
    1156 \end{cfa}
    1157 \CFA allows the declaration of local variables, \eg @y@, at the start of the @switch@ with scope across the entire @switch@ body, \ie all @case@ clauses.
    1158 \CFA disallows the declaration of local variable, \eg @z@, directly within the @switch@ body, because a declaration cannot occur immediately after a @case@ since a label can only be attached to a statement, and the use of @z@ is undefined in @case 1@ as neither storage allocation nor initialization may have occurred.
    1159 
    1160 C @switch@ provides multiple entry points into the statement body, but once an entry point is selected, control continues across \emph{all} @case@ clauses until the end of the @switch@ body, called \newterm{fall through};
    1161 @case@ clauses are made disjoint by the @break@ statement.
    1162 While the ability to fall through \emph{is} a useful form of control flow, it does not match well with programmer intuition, resulting in many errors from missing @break@ statements.
    1163 For backwards compatibility, \CFA provides a \emph{new} control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through:
    1164 \begin{cquote}
    1165 \lstDeleteShortInline@%
    1166 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    1167 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    1168 \begin{cfa}
    1169 `choose` ( day ) {
    1170   case Mon~Thu:  // program
    1171 
    1172   case Fri:  // program
    1173         wallet += pay;
    1174         `fallthrough;`
    1175   case Sat:  // party
    1176         wallet -= party;
    1177 
    1178   case Sun:  // rest
    1179 
    1180   default:  // error
    1181 }
    1182 \end{cfa}
    1183 &
    1184 \begin{cfa}
    1185 switch ( day ) {
    1186   case Mon: case Tue: case Wed: case Thu:  // program
    1187         `break;`
    1188   case Fri:  // program
    1189         wallet += pay;
    1190 
    1191   case Sat:  // party
    1192         wallet -= party;
    1193         `break;`
    1194   case Sun:  // rest
    1195         `break;`
    1196   default:  // error
    1197 }
    1198 \end{cfa}
    1199 \end{tabular}
    1200 \lstMakeShortInline@%
    1201 \end{cquote}
    1202 Collectively, these enhancements reduce programmer burden and increase readability and safety.
    1203 
    1204 \begin{comment}
    1205 Forgotten @break@ statements at the end of @switch@ cases are a persistent sort of programmer error in C, and the @break@ statements themselves introduce visual clutter and an un-C-like keyword-based block delimiter.
    1206 \CFA addresses this error by introducing a @choose@ statement, which works identically to a @switch@ except that its default end-of-case behaviour is to break rather than to fall through for all non-empty cases.
    1207 Since empty cases like @case 7:@ in @case 7: case 11:@ still have fall-through semantics and explicit @break@ is still allowed at the end of a @choose@ case, many idiomatic uses of @switch@ in standard C can be converted to @choose@ statements by simply changing the keyword.
    1208 Where fall-through is desired for a non-empty case, it can be specified with the new @fallthrough@ statement, making @choose@ equivalently powerful to @switch@, but more concise in the common case where most non-empty cases end with a @break@ statement, as in the example below:
    1209 
    1210 \begin{cfa}
    1211 choose( i ) {
    1212         case 2:
    1213                 printf("even ");
    1214                 fallthrough;
    1215         case 3: case 5: case 7:
    1216                 printf("small prime\n");
    1217         case 4,6,8,9:
    1218                 printf("small composite\n");
    1219         case 13~19:
    1220                 printf("teen\n");
    1221         default:
    1222                 printf("something else\n");
    1223 }
    1224 \end{cfa}
    1225 \end{comment}
     1357The arguments for @enable@/@disable@ specify the exception types allowed to be propagated or postponed, respectively.
     1358Specifying no exception type is shorthand for specifying all exception types.
     1359Both @enable@ and @disable@ blocks can be nested, turning propagation on/off on entry, and on exit, the specified exception types are restored to their prior state.
     1360
     1361Finally, \CFA provides a Java like  @finally@ clause after the catch clauses:
     1362\begin{cfa}
     1363try {
     1364        ... f(); ...
     1365// catchResume or catch clauses
     1366} `finally` {
     1367        // house keeping
     1368}
     1369\end{cfa}
     1370The finally clause is always executed, i.e., if the try block ends normally or if an exception is raised.
     1371If an exception is raised and caught, the handler is run before the finally clause.
     1372Like a destructor (see Section~\ref{s:ConstructorsDestructors}), a finally clause can raise an exception but not if there is an exception being propagated.
     1373Mimicking the @finally@ clause with mechanisms like RAII is non-trivially when there are multiple types and local accesses.
    12261374
    12271375
     
    12381386S s, as[10];
    12391387\end{cfa}
    1240 However, routines manipulating aggregates must repeat the aggregate name to access its containing fields:
     1388However, functions manipulating aggregates must repeat the aggregate name to access its containing fields:
    12411389\begin{cfa}
    12421390void f( S s ) {
     
    12561404}
    12571405\end{C++}
    1258 Object-oriented nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
     1406Object-oriented nesting of member functions in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
    12591407However, for other aggregate parameters, qualification is necessary:
    12601408\begin{cfa}
     
    12861434        'with' '(' $\emph{expression-list}$ ')' $\emph{compound-statement}$
    12871435\end{cfa}
    1288 and may appear as the body of a routine or nested within a routine body.
     1436and may appear as the body of a function or nested within a function body.
    12891437Each expression in the expression-list provides a type and object.
    12901438The type must be an aggregate type.
     
    13131461Qualification or a cast is used to disambiguate.
    13141462
    1315 There is an interesting problem between parameters and the routine @with@, \eg:
     1463There is an interesting problem between parameters and the function @with@, \eg:
    13161464\begin{cfa}
    13171465void ?{}( S & s, int i ) with ( s ) {           $\C{// constructor}$
     
    13191467}
    13201468\end{cfa}
    1321 Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the routine @with@.
     1469Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the function @with@.
    13221470To solve this problem, parameters are treated like an initialized aggregate:
    13231471\begin{cfa}
     
    13271475} params;
    13281476\end{cfa}
    1329 and implicitly opened \emph{after} a routine open, to give them higher priority:
     1477and implicitly opened \emph{after} a function open, to give them higher priority:
    13301478\begin{cfa}
    13311479void ?{}( S & s, int i ) with ( s ) `with( $\emph{\color{red}params}$ )` {
     
    13551503
    13561504
    1357 \subsection{Exception Handling}
    1358 
    1359 The following framework for \CFA exception handling is in place, excluding a run-time type information and dynamic casts.
    1360 \CFA provides two forms of exception handling: \newterm{fix-up} and \newterm{recovery} (see Figure~\ref{f:CFAExceptionHandling}).
    1361 Both mechanisms provide dynamic call to a handler using dynamic name-lookup, where fix-up has dynamic return and recovery has static return from the handler.
    1362 \CFA restricts exception types to those defined by aggregate type @exception@.
    1363 The form of the raise dictates the set of handlers examined during propagation: \newterm{resumption propagation} (@resume@) only examines resumption handlers (@catchResume@); \newterm{terminating propagation} (@throw@) only examines termination handlers (@catch@).
    1364 If @resume@ or @throw@ have no exception type, it is a reresume/rethrow, meaning the currently exception continues propagation.
    1365 If there is no current exception, the reresume/rethrow results in a runtime error.
    1366 
    1367 \begin{figure}
    1368 \begin{cquote}
    1369 \lstDeleteShortInline@%
    1370 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    1371 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{Resumption}}       & \multicolumn{1}{c}{\textbf{Recovery}} \\
    1372 \begin{cfa}
    1373 `exception R { int fix; };`
    1374 void f() {
    1375         R r;
    1376         ... `resume( r );` ...
    1377         ... r.fix // control does return here after handler
    1378 }
    1379 `try` {
    1380         ... f(); ...
    1381 } `catchResume( R r )` {
    1382         ... r.fix = ...; // return correction to raise
    1383 } // dynamic return to _Resume
    1384 \end{cfa}
    1385 &
    1386 \begin{cfa}
    1387 `exception T {};`
    1388 void f() {
    1389 
    1390         ... `throw( T{} );` ...
    1391         // control does NOT return here after handler
    1392 }
    1393 `try` {
    1394         ... f(); ...
    1395 } `catch( T t )` {
    1396         ... // recover and continue
    1397 } // static return to next statement
    1398 \end{cfa}
    1399 \end{tabular}
    1400 \lstMakeShortInline@%
    1401 \end{cquote}
    1402 \caption{\CFA Exception Handling}
    1403 \label{f:CFAExceptionHandling}
    1404 \end{figure}
    1405 
    1406 The set of exception types in a list of catch clause may include both a resumption and termination handler:
    1407 \begin{cfa}
    1408 try {
    1409         ... resume( `R{}` ); ...
    1410 } catchResume( `R` r ) { ... throw( R{} ); ... } $\C{\color{red}// H1}$
    1411    catch( `R` r ) { ... }                                       $\C{\color{red}// H2}$
    1412 
    1413 \end{cfa}
    1414 The resumption propagation raises @R@ and the stack is not unwound;
    1415 the exception is caught by the @catchResume@ clause and handler H1 is invoked.
    1416 The termination propagation in handler H1 raises @R@ and the stack is unwound;
    1417 the exception is caught by the @catch@ clause and handler H2 is invoked.
    1418 The termination handler is available because the resumption propagation did not unwind the stack.
    1419 
    1420 An additional feature is conditional matching in a catch clause:
    1421 \begin{cfa}
    1422 try {
    1423         ... write( `datafile`, ... ); ...               $\C{// may throw IOError}$
    1424         ... write( `logfile`, ... ); ...
    1425 } catch ( IOError err; `err.file == datafile` ) { ... } $\C{// handle datafile error}$
    1426    catch ( IOError err; `err.file == logfile` ) { ... } $\C{// handle logfile error}$
    1427    catch ( IOError err ) { ... }                        $\C{// handler error from other files}$
    1428 \end{cfa}
    1429 where the throw inserts the failing file-handle in the I/O exception.
    1430 Conditional catch cannot be trivially mimicked by other mechanisms because once an exception is caught, handler clauses in that @try@ statement are no longer eligible..
    1431 
    1432 The resumption raise can specify an alternate stack on which to raise an exception, called a \newterm{nonlocal raise}:
    1433 \begin{cfa}
    1434 resume( $\emph{exception-type}$, $\emph{alternate-stack}$ )
    1435 resume( $\emph{alternate-stack}$ )
    1436 \end{cfa}
    1437 These overloads of @resume@ raise the specified exception or the currently propagating exception (reresume) at another coroutine or task~\cite{Delisle18}.
    1438 Nonlocal raise is restricted to resumption to provide the exception handler the greatest flexibility because processing the exception does not unwind its stack, allowing it to continue after the handle returns.
    1439 
    1440 To facilitate nonlocal exception, \CFA provides dynamic enabling and disabling of nonlocal exception-propagation.
    1441 The constructs for controlling propagation of nonlocal exceptions are the @enable@ and the @disable@ blocks:
    1442 \begin{cquote}
    1443 \lstDeleteShortInline@%
    1444 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
    1445 \begin{cfa}
    1446 enable $\emph{exception-type-list}$ {
    1447         // allow non-local resumption
    1448 }
    1449 \end{cfa}
    1450 &
    1451 \begin{cfa}
    1452 disable $\emph{exception-type-list}$ {
    1453         // disallow non-local resumption
    1454 }
    1455 \end{cfa}
    1456 \end{tabular}
    1457 \lstMakeShortInline@%
    1458 \end{cquote}
    1459 The arguments for @enable@/@disable@ specify the exception types allowed to be propagated or postponed, respectively.
    1460 Specifying no exception type is shorthand for specifying all exception types.
    1461 Both @enable@ and @disable@ blocks can be nested, turning propagation on/off on entry, and on exit, the specified exception types are restored to their prior state.
    1462 
    1463 Finally, \CFA provides a Java like  @finally@ clause after the catch clauses:
    1464 \begin{cfa}
    1465 try {
    1466         ... f(); ...
    1467 // catchResume or catch clauses
    1468 } `finally` {
    1469         // house keeping
    1470 }
    1471 \end{cfa}
    1472 The finally clause is always executed, i.e., if the try block ends normally or if an exception is raised.
    1473 If an exception is raised and caught, the handler is run before the finally clause.
    1474 Like a destructor (see Section~\ref{s:ConstructorsDestructors}), a finally clause can raise an exception but not if there is an exception being propagated.
    1475 Mimicking the @finally@ clause with mechanisms like RAII is non-trivially when there are multiple types and local accesses.
    1476 
    1477 
    14781505\section{Declarations}
    14791506
     
    15031530Is this an array of 5 pointers to integers or a pointer to an array of 5 integers?
    15041531If there is any doubt, it implies productivity and safety issues even for basic programs.
    1505 Another example of confusion results from the fact that a routine name and its parameters are embedded within the return type, mimicking the way the return value is used at the routine's call site.
    1506 For example, a routine returning a pointer to an array of integers is defined and used in the following way:
     1532Another example of confusion results from the fact that a function name and its parameters are embedded within the return type, mimicking the way the return value is used at the function's call site.
     1533For example, a function returning a pointer to an array of integers is defined and used in the following way:
    15071534\begin{cfa}
    15081535int `(*`f`())[`5`]` {...};                                      $\C{// definition}$
    15091536 ... `(*`f`())[`3`]` += 1;                                      $\C{// usage}$
    15101537\end{cfa}
    1511 Essentially, the return type is wrapped around the routine name in successive layers (like an onion).
     1538Essentially, the return type is wrapped around the function name in successive layers (like an onion).
    15121539While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice.
    15131540
    1514 \CFA provides its own type, variable and routine declarations, using a different syntax.
     1541\CFA provides its own type, variable and function declarations, using a different syntax.
    15151542The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right.
    15161543The qualifiers have the same meaning but are ordered left to right to specify a variable's type.
     
    15401567\end{cquote}
    15411568The only exception is bit field specification, which always appear to the right of the base type.
    1542 % Specifically, the character @*@ is used to indicate a pointer, square brackets @[@\,@]@ are used to represent an array or function return value, and parentheses @()@ are used to indicate a routine parameter.
     1569% Specifically, the character @*@ is used to indicate a pointer, square brackets @[@\,@]@ are used to represent an array or function return value, and parentheses @()@ are used to indicate a function parameter.
    15431570However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list.
    15441571For instance, variables @x@ and @y@ of type pointer to integer are defined in \CFA as follows:
     
    16261653\lstMakeShortInline@%
    16271654\end{cquote}
    1628 Specifiers must appear at the start of a \CFA routine declaration\footnote{\label{StorageClassSpecifier}
     1655Specifiers must appear at the start of a \CFA function declaration\footnote{\label{StorageClassSpecifier}
    16291656The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}}.
    16301657
    1631 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine @sizeof@:
     1658The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-function @sizeof@:
    16321659\begin{cquote}
    16331660\lstDeleteShortInline@%
     
    16471674\end{cquote}
    16481675
    1649 The syntax of the new routine prototype declaration follows directly from the new routine definition syntax;
     1676The syntax of the new function-prototype declaration follows directly from the new function-definition syntax;
    16501677as well, parameter names are optional, \eg:
    16511678\begin{cfa}
     
    16561683[ * int, int ] j ( int );                                       $\C{// returning pointer to int and int, with int parameter}$
    16571684\end{cfa}
    1658 This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
    1659 Like C, it is possible to declare multiple routine-prototypes in a single declaration, where the return type is distributed across \emph{all} routine names in the declaration list, \eg:
     1685This syntax allows a prototype declaration to be created by cutting and pasting source text from the function-definition header (or vice versa).
     1686Like C, it is possible to declare multiple function-prototypes in a single declaration, where the return type is distributed across \emph{all} function names in the declaration list, \eg:
    16601687\begin{cquote}
    16611688\lstDeleteShortInline@%
     
    16721699\lstMakeShortInline@%
    16731700\end{cquote}
    1674 where \CFA allows the last routine in the list to define its body.
    1675 
    1676 The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
    1677 \begin{cfa}
    1678 * [ int x ] () fp;                                                      $\C{// pointer to routine returning int with no parameters}$
    1679 * [ * int ] ( int y ) gp;                                       $\C{// pointer to routine returning pointer to int with int parameter}$
    1680 * [ ] ( int, char ) hp;                                         $\C{// pointer to routine returning no result with int and char parameters}$
    1681 * [ * int, int ] ( int ) jp;                            $\C{// pointer to routine returning pointer to int and int, with int parameter}$
    1682 \end{cfa}
    1683 Note, a routine name cannot be specified:
    1684 \begin{cfa}
    1685 * [ int x ] f () fp;                                            $\C{// routine name "f" is disallowed}$
     1701where \CFA allows the last function in the list to define its body.
     1702
     1703The syntax for pointers to \CFA functions specifies the pointer name on the right, \eg:
     1704\begin{cfa}
     1705* [ int x ] () fp;                                                      $\C{// pointer to function returning int with no parameters}$
     1706* [ * int ] ( int y ) gp;                                       $\C{// pointer to function returning pointer to int with int parameter}$
     1707* [ ] ( int, char ) hp;                                         $\C{// pointer to function returning no result with int and char parameters}$
     1708* [ * int, int ] ( int ) jp;                            $\C{// pointer to function returning pointer to int and int, with int parameter}$
     1709\end{cfa}
     1710Note, a function name cannot be specified:
     1711\begin{cfa}
     1712* [ int x ] f () fp;                                            $\C{// function name "f" is disallowed}$
    16861713\end{cfa}
    16871714
     
    19031930Destruction parameters are useful for specifying storage-management actions, such as de-initialize but not deallocate.}.
    19041931\begin{cfa}
    1905 struct VLA {
    1906         int len, * data;
    1907 };
    1908 void ?{}( VLA & vla ) with ( vla ) {            $\C{// default constructor}$
    1909         len = 10;  data = alloc( len );                 $\C{// shallow copy}$
    1910 }
    1911 void ^?{}( VLA & vla ) with ( vla ) {           $\C{// destructor}$
    1912         free( data );
    1913 }
     1932struct VLA { int len, * data; };
     1933void ?{}( VLA & vla ) with ( vla ) { len = 10;  data = alloc( len ); }  $\C{// default constructor}$
     1934void ^?{}( VLA & vla ) with ( vla ) { free( data ); } $\C{// destructor}$
    19141935{
    19151936        VLA x;                                                                  $\C{// implicit:  ?\{\}( x );}$
    19161937}                                                                                       $\C{// implicit:  ?\^{}\{\}( x );}$
    19171938\end{cfa}
    1918 (Note, the example is purposely kept simple by using shallow-copy semantics.)
    19191939@VLA@ is a \newterm{managed type}\footnote{
    19201940A managed type affects the runtime environment versus a self-contained type.}: a type requiring a non-trivial constructor or destructor, or with a field of a managed type.
     
    19241944\CFA also provides syntax for \newterm{initialization} and \newterm{copy}:
    19251945\begin{cfa}
    1926 void ?{}( VLA & vla, int size, char fill ) with ( vla ) {       $\C{// initialization}$
     1946void ?{}( VLA & vla, int size, char fill ) with ( vla ) {  $\C{// initialization}$
    19271947        len = size;  data = alloc( len, fill );
    19281948}
    1929 void ?{}( VLA & vla, VLA other ) {                      $\C{// copy}$
     1949void ?{}( VLA & vla, VLA other ) {                      $\C{// copy, shallow}$
    19301950        vla.len = other.len;  vla.data = other.data;
    19311951}
    19321952\end{cfa}
     1953(Note, the example is purposely kept simple by using shallow-copy semantics.)
    19331954An initialization constructor-call has the same syntax as a C initializer, except the initialization values are passed as arguments to a matching constructor (number and type of paremeters).
    19341955\begin{cfa}
     
    19441965\begin{cfa}
    19451966{
    1946         VLA x,  y = { 20, 0x01 },  z = y;
    1947         // implicit:  ?{}( x );  ?{}( y, 20, 0x01 );  ?{}( z, y ); z points to y
     1967        VLA  x,            y = { 20, 0x01 },     z = y; $\C{// z points to y}$
     1968        //      ?{}( x );  ?{}( y, 20, 0x01 );  ?{}( z, y );
    19481969        ^x{};                                                                   $\C{// deallocate x}$
    19491970        x{};                                                                    $\C{// reallocate x}$
     
    19521973        y{ x };                                                                 $\C{// reallocate y, points to x}$
    19531974        x{};                                                                    $\C{// reallocate x, not pointing to y}$
    1954         // implicit:  ^?{}(z);  ^?{}(y);  ^?{}(x);
     1975        // ^?{}(z);  ^?{}(y);  ^?{}(x);
    19551976}
    19561977\end{cfa}
     
    19832004C already includes limited polymorphism for literals -- @0@ can be either an integer or a pointer literal, depending on context, while the syntactic forms of literals of the various integer and float types are very similar, differing from each other only in suffix.
    19842005In keeping with the general \CFA approach of adding features while respecting the ``C-style'' of doing things, C's polymorphic constants and typed literal syntax are extended to interoperate with user-defined types, while maintaining a backwards-compatible semantics.
    1985 A trivial example is allowing the underscore to separate prefixes, digits, and suffixes in all \CFA constants, as in Ada, \eg @0x`_`1.ffff`_`ffff`_`p`_`128`_`l@.
     2006A trivial example is allowing the underscore, as in Ada, to separate prefixes, digits, and suffixes in all \CFA constants, \eg @0x`_`1.ffff`_`ffff`_`p`_`128`_`l@.
     2007
     2008
     2009\subsection{Integral Suffixes}
     2010
     2011Additional integral suffixes are added to cover all the integral types and lengths.
     2012\begin{cquote}
     2013\lstDeleteShortInline@%
     2014\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}
     2015\begin{cfa}
     201620`_hh`     // signed char
     201721`_hhu`   // unsigned char
     201822`_h`       // signed short int
     201923`_uh`     // unsigned short int
     202024`z`         // size_t
     2021\end{cfa}
     2022&
     2023\begin{cfa}
     202420`_L8`      // int8_t
     202521`_ul8`     // uint8_t
     202622`_l16`     // int16_t
     202723`_ul16`   // uint16_t
     202824`_l32`     // int32_t
     2029\end{cfa}
     2030&
     2031\begin{cfa}
     203225`_ul32`      // uint32_t
     203326`_l64`        // int64_t
     203427`_l64u`      // uint64_t
     203526`_L128`     // int128
     203627`_L128u`   // unsigned int128
     2037\end{cfa}
     2038\end{tabular}
     2039\lstMakeShortInline@%
     2040\end{cquote}
    19862041
    19872042
     
    20002055
    20012056
    2002 \subsection{Integral Suffixes}
    2003 
    2004 Additional integral suffixes are added to cover all the integral types and lengths.
    2005 \begin{cquote}
     2057\subsection{User Literals}
     2058
     2059For readability, it is useful to associate units to scale literals, \eg weight (stone, pound, kilogram) or time (seconds, minutes, hours).
     2060The left of Figure~\ref{f:UserLiteral} shows the \CFA alternative call-syntax (literal argument before function name), using the backquote, to convert basic literals into user literals.
     2061The backquote is a small character, making the unit (function name) predominate.
     2062For examples, the multi-precision integers in Section~\ref{s:MultiPrecisionIntegers} make use of user literals:
     2063{\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}
     2064\begin{cfa}
     2065y = 9223372036854775807L|`mp| * 18446744073709551615UL|`mp|;
     2066y = "12345678901234567890123456789"|`mp| + "12345678901234567890123456789"|`mp|;
     2067\end{cfa}
     2068Because \CFA uses a standard function, all types and literals are applicable, as well as overloading and conversions.
     2069}%
     2070
     2071The right of Figure~\ref{f:UserLiteral} shows the equivalent \CC version using the underscore for the call-syntax.
     2072However, \CC restricts the types, \eg @unsigned long long int@ and @long double@ to represent integral and floating literals.
     2073After which, user literals must match (no conversions);
     2074hence, it is necessary to overload the unit with all appropriate types.
     2075Finally, the use of the single quote as a separator is restricted to digits, precluding its use in the literal prefix or suffix, and causes problems with most IDEs, which must be extended to deal with this alternate use of the single quote.
     2076
     2077\begin{figure}
     2078\centering
     2079\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}
    20062080\lstDeleteShortInline@%
    2007 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}
    2008 \begin{cfa}
    2009 20_hh     // signed char
    2010 21_hhu   // unsigned char
    2011 22_h      // signed short int
    2012 23_uh    // unsigned short int
    2013 24z        // size_t
    2014 \end{cfa}
    2015 &
    2016 \begin{cfa}
    2017 20_L8     // int8_t
    2018 21_ul8    // uint8_t
    2019 22_l16    // int16_t
    2020 23_ul16  // uint16_t
    2021 24_l32    // int32_t
    2022 \end{cfa}
    2023 &
    2024 \begin{cfa}
    2025 25_ul32      // uint32_t
    2026 26_l64        // int64_t
    2027 27_l64u      // uint64_t
    2028 26_L128     // int128
    2029 27_L128u  // unsigned int128
     2081\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
     2082\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{\CC}}      \\
     2083\begin{cfa}
     2084struct W {
     2085        double stones;
     2086};
     2087void ?{}( W & w ) { w.stones = 0; }
     2088void ?{}( W & w, double w ) { w.stones = w; }
     2089W ?+?( W l, W r ) {
     2090        return (W){ l.stones + r.stones };
     2091}
     2092W |?`st|( double w ) { return (W){ w }; }
     2093W |?`lb|( double w ) { return (W){ w / 14.0 }; }
     2094W |?`kg|( double w ) { return (W) { w * 0.16 }; }
     2095
     2096
     2097
     2098int main() {
     2099        W w, heavy = { 20 };
     2100        w = 155|`lb|;
     2101        w = 0b_1111|`st|;
     2102        w = 0_233|`lb|;
     2103        w = 0x_9b_u|`kg|;
     2104        w = 5.5|`st| + 8|`kg| + 25.01|`lb| + heavy;
     2105}
     2106\end{cfa}
     2107&
     2108\begin{cfa}
     2109struct W {
     2110    double stones;
     2111    W() { stones = 0.0; }
     2112    W( double w ) { stones = w; }
     2113};
     2114W operator+( W l, W r ) {
     2115        return W( l.stones + r.stones );
     2116}
     2117W |operator"" _st|( unsigned long long int w ) { return W( w ); }
     2118W |operator"" _lb|( unsigned long long int w ) { return W( w / 14.0 ); }
     2119W |operator"" _kg|( unsigned long long int w ) { return W( w * 0.16 ); }
     2120W |operator"" _st|( long double w ) { return W( w ); }
     2121W |operator"" _lb|( long double w ) { return W( w / 14.0 ); }
     2122W |operator"" _kg|( long double w ) { return W( w * 0.16 ); }
     2123int main() {
     2124        W w, heavy = { 20 };
     2125        w = 155|_lb|;
     2126        w = 0b1111|_lb|;       // error, binary unsupported
     2127        w = 0${\color{red}'}$233|_lb|;          // quote separator
     2128        w = 0x9b|_kg|;
     2129        w = 5.5d|_st| + 8|_kg| + 25.01|_lb| + heavy;
     2130}
    20302131\end{cfa}
    20312132\end{tabular}
    20322133\lstMakeShortInline@%
    2033 \end{cquote}
    2034 
    2035 
    2036 \subsection{Units}
    2037 
    2038 Alternative call syntax (literal argument before routine name) to convert basic literals into user literals.
    2039 
    2040 {\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}
    2041 \begin{cfa}
    2042 struct Weight { double stones; };
    2043 void ?{}( Weight & w ) { w.stones = 0; }        $\C{// operations}$
    2044 void ?{}( Weight & w, double w ) { w.stones = w; }
    2045 Weight ?+?( Weight l, Weight r ) { return (Weight){ l.stones + r.stones }; }
    2046 
    2047 Weight |?`st|( double w ) { return (Weight){ w }; } $\C{// backquote for units}$
    2048 Weight |?`lb|( double w ) { return (Weight){ w / 14.0 }; }
    2049 Weight |?`kg|( double w ) { return (Weight) { w * 0.1575}; }
    2050 
    2051 int main() {
    2052         Weight w, heavy = { 20 };                               $\C{// 20 stone}$
    2053         w = 155|`lb|;
    2054         w = 0x_9b_u|`lb|;                                               $\C{// hexadecimal unsigned weight (155)}$
    2055         w = 0_233|`lb|;                                                 $\C{// octal weight (155)}$
    2056         w = 5|`st| + 8|`kg| + 25|`lb| + heavy;
    2057 }
    2058 \end{cfa}
    2059 }%
     2134\caption{User Literal}
     2135\label{f:UserLiteral}
     2136\end{figure}
    20602137
    20612138
     
    20672144In many cases, the interface is an inline wrapper providing overloading during compilation but zero cost at runtime.
    20682145The following sections give a glimpse of the interface reduction to many C libraries.
    2069 In many cases, @signed@/@unsigned@ @char@ and @short@ routines are available (but not shown) to ensure expression computations remain in a single type, as conversions can distort results.
     2146In many cases, @signed@/@unsigned@ @char@, @short@, and @_Complex@ functions are available (but not shown) to ensure expression computations remain in a single type, as conversions can distort results.
    20702147
    20712148
     
    20952172\begin{cquote}
    20962173\lstDeleteShortInline@%
    2097 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    2098 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
     2174\lstset{basicstyle=\linespread{0.9}\sf\small}
     2175\begin{tabular}{@{}l@{\hspace{0.5\parindentlnth}}l@{}}
     2176\multicolumn{1}{c@{\hspace{0.5\parindentlnth}}}{\textbf{\CFA}}  & \multicolumn{1}{c}{\textbf{C}}        \\
    20992177\begin{cfa}
    21002178MIN
    21012179MAX
    2102 M_PI
    2103 M_E
    2104 \end{cfa}
    2105 &
    2106 \begin{cfa}
    2107 SCHAR_MIN, CHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, LLONG_MIN,
    2108 SCHAR_MAX, UCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX,
    2109 M_PI, M_PIl, M_CPI, M_CPIl,
    2110 M_E, M_El, M_CE, M_CEl
     2180PI
     2181E
     2182\end{cfa}
     2183&
     2184\begin{cfa}
     2185SCHAR_MIN, CHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, LLONG_MIN, FLT_MIN, DBL_MIN, LDBL_MIN
     2186SCHAR_MAX, UCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX, FLT_MAX, DBL_MAX, LDBL_MAX
     2187M_PI, M_PIl
     2188M_E, M_El
    21112189\end{cfa}
    21122190\end{tabular}
     
    21172195\subsection{Math}
    21182196
    2119 C library @math.h@ provides many mathematical routines.
    2120 \CFA routine overloading is used to condense these mathematical routines, \eg:
     2197C library @math.h@ provides many mathematical functions.
     2198\CFA function overloading is used to condense these mathematical functions, \eg:
    21212199\begin{cquote}
    21222200\lstDeleteShortInline@%
     
    21372215\lstMakeShortInline@%
    21382216\end{cquote}
    2139 The result is a significant reduction in names to access math routines, \eg:
     2217The result is a significant reduction in names to access math functions, \eg:
    21402218\begin{cquote}
    21412219\lstDeleteShortInline@%
     
    21562234\lstMakeShortInline@%
    21572235\end{cquote}
    2158 While \Celeven has type-generic math~\cite[\S~7.25]{C11} in @tgmath.h@ to provide a similar mechanism, these macros are limited, matching a routine name with a single set of floating type(s).
     2236While \Celeven has type-generic math~\cite[\S~7.25]{C11} in @tgmath.h@ to provide a similar mechanism, these macros are limited, matching a function name with a single set of floating type(s).
    21592237For example, it is impossible to overload @atan@ for both one and two arguments;
    2160 instead the names @atan@ and @atan2@ are required.
    2161 The key observation is that only a restricted set of type-generic macros are provided for a limited set of routine names, which do not generalize across the type system, as in \CFA.
     2238instead the names @atan@ and @atan2@ are required (see Section~\ref{s:NameOverloading}).
     2239The key observation is that only a restricted set of type-generic macros are provided for a limited set of function names, which do not generalize across the type system, as in \CFA.
    21622240
    21632241
    21642242\subsection{Standard}
    21652243
    2166 C library @stdlib.h@ provides many general routines.
    2167 \CFA routine overloading is used to condense these utility routines, \eg:
     2244C library @stdlib.h@ provides many general functions.
     2245\CFA function overloading is used to condense these utility functions, \eg:
    21682246\begin{cquote}
    21692247\lstDeleteShortInline@%
     
    21842262\lstMakeShortInline@%
    21852263\end{cquote}
    2186 The result is a significant reduction in names to access utility routines, \eg:
     2264The result is a significant reduction in names to access utility functions, \eg:
    21872265\begin{cquote}
    21882266\lstDeleteShortInline@%
     
    22032281\lstMakeShortInline@%
    22042282\end{cquote}
    2205 In additon, there are polymorphic routines, like @min@ and @max@, which work on any type with operators @?<?@ or @?>?@.
     2283In additon, there are polymorphic functions, like @min@ and @max@, which work on any type with operators @?<?@ or @?>?@.
    22062284
    22072285The following shows one example where \CFA \emph{extends} an existing standard C interface to reduce complexity and provide safety.
     
    22202298An array may be filled, resized, or aligned.
    22212299\end{description}
    2222 Table~\ref{t:StorageManagementOperations} shows the capabilities provided by C/\Celeven allocation-routines and how all the capabilities can be combined into two \CFA routines.
    2223 
    2224 \CFA storage-management routines extend the C equivalents by overloading, providing shallow type-safety, and removing the need to specify the base allocation-size.
    2225 The following example contrasts \CFA and C storage-allocation operation performing the same operations with the same type safety:
    2226 \begin{cquote}
    2227 \begin{cfa}[aboveskip=0pt]
    2228 size_t  dim = 10;                                                       $\C{// array dimension}$
    2229 char fill = '\xff';                                                     $\C{// initialization fill value}$
    2230 int * ip;
    2231 \end{cfa}
    2232 \lstDeleteShortInline@%
    2233 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    2234 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    2235 \begin{cfa}
    2236 ip = alloc();
    2237 ip = alloc( fill );
    2238 ip = alloc( dim );
    2239 ip = alloc( dim, fill );
    2240 ip = alloc( ip, 2 * dim );
    2241 ip = alloc( ip, 4 * dim, fill );
    2242 
    2243 ip = align_alloc( 16 );
    2244 ip = align_alloc( 16, fill );
    2245 ip = align_alloc( 16, dim );
    2246 ip = align_alloc( 16, dim, fill );
    2247 \end{cfa}
    2248 &
    2249 \begin{cfa}
    2250 ip = (int *)malloc( sizeof( int ) );
    2251 ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, sizeof( int ) );
    2252 ip = (int *)malloc( dim * sizeof( int ) );
    2253 ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
    2254 ip = (int *)realloc( ip, 2 * dim * sizeof( int ) );
    2255 ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); memset( ip, fill, 4 * dim * sizeof( int ) );
    2256 
    2257 ip = memalign( 16, sizeof( int ) );
    2258 ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) );
    2259 ip = memalign( 16, dim * sizeof( int ) );
    2260 ip = memalign( 16, dim * sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
    2261 \end{cfa}
    2262 \end{tabular}
    2263 \lstMakeShortInline@%
    2264 \end{cquote}
    2265 Variadic @new@ (see Section~\ref{sec:variadic-tuples}) cannot support the same overloading because extra parameters are for initialization.
    2266 Hence, there are @new@ and @anew@ routines for single and array variables, and the fill value is the arguments to the constructor, \eg:
    2267 \begin{cfa}
    2268 struct S { int i, j; };
    2269 void ?{}( S & s, int i, int j ) { s.i = i; s.j = j; }
    2270 S * s = new( 2, 3 );                                            $\C{// allocate storage and run constructor}$
    2271 S * as = anew( dim, 2, 3 );                                     $\C{// each array element initialized to 2, 3}$
    2272 \end{cfa}
    2273 Note, \CC can only initialization array elements via the default constructor.
    2274 
    2275 Finally, the \CFA memory-allocator has \newterm{sticky properties} for dynamic storage: fill and alignment are remembered with an object's storage in the heap.
    2276 When a @realloc@ is performed, the sticky properties are respected, so that new storage is correctly aligned and initialized with the fill character.
     2300Table~\ref{t:StorageManagementOperations} shows the capabilities provided by C/\Celeven allocation-functions and how all the capabilities can be combined into two \CFA functions.
     2301\CFA storage-management functions extend the C equivalents by overloading, providing shallow type-safety, and removing the need to specify the base allocation-size.
     2302Figure~\ref{f:StorageAllocation} contrasts \CFA and C storage-allocation operation performing the same operations with the same type safety.
    22772303
    22782304\begin{table}
     
    23002326\end{table}
    23012327
     2328\begin{figure}
     2329\centering
     2330\begin{cquote}
     2331\begin{cfa}[aboveskip=0pt]
     2332size_t  dim = 10;                                                       $\C{// array dimension}$
     2333char fill = '\xff';                                                     $\C{// initialization fill value}$
     2334int * ip;
     2335\end{cfa}
     2336\lstDeleteShortInline@%
     2337\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
     2338\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
     2339\begin{cfa}
     2340ip = alloc();
     2341ip = alloc( fill );
     2342ip = alloc( dim );
     2343ip = alloc( dim, fill );
     2344ip = alloc( ip, 2 * dim );
     2345ip = alloc( ip, 4 * dim, fill );
     2346
     2347ip = align_alloc( 16 );
     2348ip = align_alloc( 16, fill );
     2349ip = align_alloc( 16, dim );
     2350ip = align_alloc( 16, dim, fill );
     2351\end{cfa}
     2352&
     2353\begin{cfa}
     2354ip = (int *)malloc( sizeof( int ) );
     2355ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, sizeof( int ) );
     2356ip = (int *)malloc( dim * sizeof( int ) );
     2357ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
     2358ip = (int *)realloc( ip, 2 * dim * sizeof( int ) );
     2359ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); memset( ip, fill, 4 * dim * sizeof( int ) );
     2360
     2361ip = memalign( 16, sizeof( int ) );
     2362ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) );
     2363ip = memalign( 16, dim * sizeof( int ) );
     2364ip = memalign( 16, dim * sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
     2365\end{cfa}
     2366\end{tabular}
     2367\lstMakeShortInline@%
     2368\end{cquote}
     2369\caption{\CFA versus C Storage-Allocation}
     2370\label{f:StorageAllocation}
     2371\end{figure}
     2372
     2373Variadic @new@ (see Section~\ref{sec:variadic-tuples}) cannot support the same overloading because extra parameters are for initialization.
     2374Hence, there are @new@ and @anew@ functions for single and array variables, and the fill value is the arguments to the constructor, \eg:
     2375\begin{cfa}
     2376struct S { int i, j; };
     2377void ?{}( S & s, int i, int j ) { s.i = i; s.j = j; }
     2378S * s = new( 2, 3 );                                            $\C{// allocate storage and run constructor}$
     2379S * as = anew( dim, 2, 3 );                                     $\C{// each array element initialized to 2, 3}$
     2380\end{cfa}
     2381Note, \CC can only initialization array elements via the default constructor.
     2382
     2383Finally, the \CFA memory-allocator has \newterm{sticky properties} for dynamic storage: fill and alignment are remembered with an object's storage in the heap.
     2384When a @realloc@ is performed, the sticky properties are respected, so that new storage is correctly aligned and initialized with the fill character.
     2385
    23022386
    23032387\subsection{I/O}
     
    23872471}%
    23882472\end{itemize}
    2389 There are routines to set and get the separator string, and manipulators to toggle separation on and off in the middle of output.
     2473There are functions to set and get the separator string, and manipulators to toggle separation on and off in the middle of output.
    23902474
    23912475
     
    23942478
    23952479\CFA has an interface to the GMP multi-precision signed-integers~\cite{GMP}, similar to the \CC interface provided by GMP.
    2396 The \CFA interface wraps GMP routines into operator routines to make programming with multi-precision integers identical to using fixed-sized integers.
     2480The \CFA interface wraps GMP functions into operator functions to make programming with multi-precision integers identical to using fixed-sized integers.
    23972481The \CFA type name for multi-precision signed-integers is @Int@ and the header file is @gmp@.
    23982482The following multi-precision factorial programs contrast using GMP with the \CFA and C interfaces.
     
    24392523Since all these languages share a subset essentially comprising standard C, maximal-performance benchmarks would show little runtime variance, other than in length and clarity of source code.
    24402524A more illustrative benchmark measures the costs of idiomatic usage of each language's features.
    2441 Figure~\ref{fig:BenchmarkTest} shows the \CFA benchmark tests for a generic stack based on a singly linked-list, a generic pair-data-structure, and a variadic @print@ routine similar to that in Section~\ref{sec:variadic-tuples}.
     2525Figure~\ref{fig:BenchmarkTest} shows the \CFA benchmark tests for a generic stack based on a singly linked-list, a generic pair-data-structure, and a variadic @print@ function similar to that in Section~\ref{sec:variadic-tuples}.
    24422526The benchmark test is similar for C and \CC.
    24432527The experiment uses element types @int@ and @pair(_Bool, char)@, and pushes $N=40M$ elements on a generic stack, copies the stack, clears one of the stacks, finds the maximum value in the other stack, and prints $N/2$ (to reduce graph height) constants.
     
    24462530\begin{cfa}[xleftmargin=3\parindentlnth,aboveskip=0pt,belowskip=0pt]
    24472531int main( int argc, char * argv[] ) {
    2448         FILE * out = fopen( "cfa-out.txt", "w" );
    2449         int maxi = 0, vali = 42;
    2450         stack(int) si, ti;
    2451 
    2452         REPEAT_TIMED( "push_int", N, push( &si, vali ); )
    2453         TIMED( "copy_int", ti = si; )
    2454         TIMED( "clear_int", clear( &si ); )
    2455         REPEAT_TIMED( "pop_int", N,
    2456                 int xi = pop( &ti ); if ( xi > maxi ) { maxi = xi; } )
    2457         REPEAT_TIMED( "print_int", N/2, print( out, vali, ":", vali, "\n" ); )
    2458 
    2459         pair(_Bool, char) maxp = { (_Bool)0, '\0' }, valp = { (_Bool)1, 'a' };
    2460         stack(pair(_Bool, char)) sp, tp;
    2461 
    2462         REPEAT_TIMED( "push_pair", N, push( &sp, valp ); )
    2463         TIMED( "copy_pair", tp = sp; )
    2464         TIMED( "clear_pair", clear( &sp ); )
    2465         REPEAT_TIMED( "pop_pair", N,
    2466                 pair(_Bool, char) xp = pop( &tp ); if ( xp > maxp ) { maxp = xp; } )
    2467         REPEAT_TIMED( "print_pair", N/2, print( out, valp, ":", valp, "\n" ); )
    2468         fclose(out);
     2532        ofstream out = { "cfa-out.txt" };
     2533        int max = 0, val = 42;
     2534        stack( int ) s, t;
     2535
     2536        REPEAT_TIMED( "push_int", N, push( s, val ); )
     2537        TIMED( "copy_int", t = s; )
     2538        TIMED( "clear_int", clear( s ); )
     2539        REPEAT_TIMED( "pop_int", N, int v = pop( t ); max = max( v, max ); )
     2540        REPEAT_TIMED( "print_int", N/2, out | val | ':' | val | endl; )
     2541
     2542        pair( _Bool, char ) max = { false, '\0' }, val = { true, 'a' };
     2543        stack( pair( _Bool, char ) ) s, t;
     2544
     2545        REPEAT_TIMED( "push_pair", N, push( s, val ); )
     2546        TIMED( "copy_pair", t = s; )
     2547        TIMED( "clear_pair", clear( s ); )
     2548        REPEAT_TIMED( "pop_pair", N, pair(_Bool, char) v = pop( t ); max = max( v, max ); )
     2549        REPEAT_TIMED( "print_pair", N/2, out | val | ':' | val | endl; )
    24692550}
    24702551\end{cfa}
     
    25372618\CC is the most similar language to \CFA;
    25382619both are extensions to C with source and runtime backwards compatibility.
    2539 The fundamental difference is in their engineering approach to C compatibility and programmer expectation.
    2540 While \CC provides good backwards compatibility with C, it has a steep learning curve for many of its extensions.
     2620The fundamental difference is the engineering approach to maintain C compatibility and programmer expectation.
     2621While \CC provides good compatibility with C, it has a steep learning curve for many of its extensions.
    25412622For example, polymorphism is provided via three disjoint mechanisms: overloading, inheritance, and templates.
    25422623The overloading is restricted because resolution does not use the return type, inheritance requires learning object-oriented programming and coping with a restricted nominal-inheritance hierarchy, templates cannot be separately compiled resulting in compilation/code bloat and poor error messages, and determining how these mechanisms interact and which to use is confusing.
    25432624In contrast, \CFA has a single facility for polymorphic code supporting type-safe separate-compilation of polymorphic functions and generic (opaque) types, which uniformly leverage the C procedural paradigm.
    2544 The key mechanism to support separate compilation is \CFA's \emph{explicit} use of assumed properties for a type.
    2545 Until \CC concepts~\cite{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way to specify the requirements of a generic function in code beyond compilation errors during template expansion;
     2625The key mechanism to support separate compilation is \CFA's \emph{explicit} use of assumed type properties.
     2626Until \CC concepts~\cite{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way to specify the requirements of a generic function beyond compilation errors during template expansion;
    25462627furthermore, \CC concepts are restricted to template polymorphism.
    25472628
     
    25942675
    25952676
     2677\subsection{Control Structures / Declarations / Literals}
     2678
     2679
    25962680\section{Conclusion and Future Work}
    25972681
     
    26202704
    26212705The authors would like to recognize the design assistance of Glen Ditchfield, Richard Bilson, and Thierry Delisle on the features described in this paper, and thank Magnus Madsen for feedback in the writing.
    2622 %This work is supported in part by a corporate partnership with \grantsponsor{Huawei}{Huawei Ltd.}{http://www.huawei.com}, and Aaron Moss and Peter Buhr are funded by the \grantsponsor{Natural Sciences and Engineering Research Council} of Canada.
     2706This work is supported through a corporate partnership with Huawei Ltd.\ (\url{http://www.huawei.com}), and Aaron Moss and Peter Buhr are funded by the Natural Sciences and Engineering Research Council of Canada.
     2707
    26232708% the first author's \grantsponsor{NSERC-PGS}{NSERC PGS D}{http://www.nserc-crsng.gc.ca/Students-Etudiants/PG-CS/BellandPostgrad-BelletSuperieures_eng.asp} scholarship.
    26242709
     
    26402725\CFA
    26412726\begin{cfa}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt]
     2727forall(otype T) struct stack_node;
     2728forall(otype T) struct stack {
     2729        stack_node(T) * head;
     2730};
    26422731forall(otype T) struct stack_node {
    26432732        T value;
    26442733        stack_node(T) * next;
    26452734};
    2646 forall(otype T) void ?{}(stack(T) * s) { (&s->head){ 0 }; }
    2647 forall(otype T) void ?{}(stack(T) * s, stack(T) t) {
    2648         stack_node(T) ** crnt = &s->head;
     2735forall(otype T) void ?{}( stack(T) & s ) { (s.head){ 0 }; }
     2736forall(otype T) void ?{}( stack(T) & s, stack(T) t ) {
     2737        stack_node(T) ** crnt = &s.head;
    26492738        for ( stack_node(T) * next = t.head; next; next = next->next ) {
    2650                 *crnt = ((stack_node(T) *)malloc()){ next->value }; /***/
     2739                stack_node(T) * new_node = ((stack_node(T)*)malloc());
     2740                (*new_node){ next->value }; /***/
     2741                *crnt = new_node;
    26512742                stack_node(T) * acrnt = *crnt;
    26522743                crnt = &acrnt->next;
     
    26542745        *crnt = 0;
    26552746}
    2656 forall(otype T) stack(T) ?=?(stack(T) * s, stack(T) t) {
    2657         if ( s->head == t.head ) return *s;
    2658         clear(s);
     2747forall(otype T) stack(T) ?=?( stack(T) & s, stack(T) t ) {
     2748        if ( s.head == t.head ) return s;
     2749        clear( s );
    26592750        s{ t };
    2660         return *s;
    2661 }
    2662 forall(otype T) void ^?{}(stack(T) * s) { clear(s); }
    2663 forall(otype T) _Bool empty(const stack(T) * s) { return s->head == 0; }
    2664 forall(otype T) void push(stack(T) * s, T value) {
    2665         s->head = ((stack_node(T) *)malloc()){ value, s->head }; /***/
    2666 }
    2667 forall(otype T) T pop(stack(T) * s) {
    2668         stack_node(T) * n = s->head;
    2669         s->head = n->next;
    2670         T x = n->value;
    2671         ^n{};
    2672         free(n);
    2673         return x;
    2674 }
    2675 forall(otype T) void clear(stack(T) * s) {
    2676         for ( stack_node(T) * next = s->head; next; ) {
     2751        return s;
     2752}
     2753forall(otype T) void ^?{}( stack(T) & s) { clear( s ); }
     2754forall(otype T) _Bool empty( const stack(T) & s ) { return s.head == 0; }
     2755forall(otype T) void push( stack(T) & s, T value ) {
     2756        stack_node(T) * new_node = ((stack_node(T)*)malloc());
     2757        (*new_node){ value, s.head }; /***/
     2758        s.head = new_node;
     2759}
     2760forall(otype T) T pop( stack(T) & s ) {
     2761        stack_node(T) * n = s.head;
     2762        s.head = n->next;
     2763        T v = n->value;
     2764        delete( n );
     2765        return v;
     2766}
     2767forall(otype T) void clear( stack(T) & s ) {
     2768        for ( stack_node(T) * next = s.head; next; ) {
    26772769                stack_node(T) * crnt = next;
    26782770                next = crnt->next;
    2679                 delete(crnt);
     2771                delete( crnt );
    26802772        }
    2681         s->head = 0;
     2773        s.head = 0;
    26822774}
    26832775\end{cfa}
     
    28272919
    28282920
    2829 \begin{comment}
    2830 
    2831 \subsubsection{bench.h}
    2832 (\texttt{bench.hpp} is similar.)
    2833 
    2834 \lstinputlisting{evaluation/bench.h}
    2835 
    2836 \subsection{C}
    2837 
    2838 \subsubsection{c-stack.h} ~
    2839 
    2840 \lstinputlisting{evaluation/c-stack.h}
    2841 
    2842 \subsubsection{c-stack.c} ~
    2843 
    2844 \lstinputlisting{evaluation/c-stack.c}
    2845 
    2846 \subsubsection{c-pair.h} ~
    2847 
    2848 \lstinputlisting{evaluation/c-pair.h}
    2849 
    2850 \subsubsection{c-pair.c} ~
    2851 
    2852 \lstinputlisting{evaluation/c-pair.c}
    2853 
    2854 \subsubsection{c-print.h} ~
    2855 
    2856 \lstinputlisting{evaluation/c-print.h}
    2857 
    2858 \subsubsection{c-print.c} ~
    2859 
    2860 \lstinputlisting{evaluation/c-print.c}
    2861 
    2862 \subsubsection{c-bench.c} ~
    2863 
    2864 \lstinputlisting{evaluation/c-bench.c}
    2865 
    2866 \subsection{\CFA}
    2867 
    2868 \subsubsection{cfa-stack.h} ~
    2869 
    2870 \lstinputlisting{evaluation/cfa-stack.h}
    2871 
    2872 \subsubsection{cfa-stack.c} ~
    2873 
    2874 \lstinputlisting{evaluation/cfa-stack.c}
    2875 
    2876 \subsubsection{cfa-print.h} ~
    2877 
    2878 \lstinputlisting{evaluation/cfa-print.h}
    2879 
    2880 \subsubsection{cfa-print.c} ~
    2881 
    2882 \lstinputlisting{evaluation/cfa-print.c}
    2883 
    2884 \subsubsection{cfa-bench.c} ~
    2885 
    2886 \lstinputlisting{evaluation/cfa-bench.c}
    2887 
    2888 \subsection{\CC}
    2889 
    2890 \subsubsection{cpp-stack.hpp} ~
    2891 
    2892 \lstinputlisting[language=c++]{evaluation/cpp-stack.hpp}
    2893 
    2894 \subsubsection{cpp-print.hpp} ~
    2895 
    2896 \lstinputlisting[language=c++]{evaluation/cpp-print.hpp}
    2897 
    2898 \subsubsection{cpp-bench.cpp} ~
    2899 
    2900 \lstinputlisting[language=c++]{evaluation/cpp-bench.cpp}
    2901 
    2902 \subsection{\CCV}
    2903 
    2904 \subsubsection{object.hpp} ~
    2905 
    2906 \lstinputlisting[language=c++]{evaluation/object.hpp}
    2907 
    2908 \subsubsection{cpp-vstack.hpp} ~
    2909 
    2910 \lstinputlisting[language=c++]{evaluation/cpp-vstack.hpp}
    2911 
    2912 \subsubsection{cpp-vstack.cpp} ~
    2913 
    2914 \lstinputlisting[language=c++]{evaluation/cpp-vstack.cpp}
    2915 
    2916 \subsubsection{cpp-vprint.hpp} ~
    2917 
    2918 \lstinputlisting[language=c++]{evaluation/cpp-vprint.hpp}
    2919 
    2920 \subsubsection{cpp-vbench.cpp} ~
    2921 
    2922 \lstinputlisting[language=c++]{evaluation/cpp-vbench.cpp}
    2923 \end{comment}
    2924 
    29252921\end{document}
    29262922
  • doc/papers/general/evaluation/cfa-bench.c

    r094476d rcaa649b  
    1 #include <stdio.h>
     1#include <fstream>
     2#include <stdlib>
     3#include <stdbool.h>
    24#include "bench.h"
    35#include "cfa-stack.h"
     
    57#include "cfa-print.h"
    68
    7 int main( int argc, char *argv[] ) {
    8         FILE * out = fopen( "/dev/null", "w" );
    9         int maxi = 0, vali = 42;
    10         stack(int) si, ti;
     9int main( int argc, char * argv[] ) {
     10        ofstream out = { "/dev/null" };
     11        int max = 0, val = 42;
     12        stack( int ) s, t;
    1113
    12         REPEAT_TIMED( "push_int", N, push( &si, vali ); )
    13         TIMED( "copy_int", ti = si; )
    14         TIMED( "clear_int", clear( &si ); )
    15         REPEAT_TIMED( "pop_int", N,
    16                 int xi = pop( &ti );
    17                 if ( xi > maxi ) { maxi = xi; } )
    18         REPEAT_TIMED( "print_int", N/2, print( out, vali, ":", vali, "\n" ); )
     14        REPEAT_TIMED( "push_int", N, push( s, val ); )
     15        TIMED( "copy_int", t = s; )
     16        TIMED( "clear_int", clear( s ); )
     17        REPEAT_TIMED( "pop_int", N, int x = pop( t ); max = max( x, max ); )
     18        REPEAT_TIMED( "print_int", N/2, out | val | ':' | val | endl; )
    1919
    20         pair(_Bool, char) maxp = { (_Bool)0, '\0' }, valp = { (_Bool)1, 'a' };
    21         stack(pair(_Bool, char)) sp, tp;
     20        pair( _Bool, char ) max = { (_Bool)false, '\0' }, val = { (_Bool)true, 'a' };
     21        stack( pair( _Bool, char ) ) s, t;
    2222
    23         REPEAT_TIMED( "push_pair", N, push( &sp, valp ); )
    24         TIMED( "copy_pair", tp = sp; )
    25         TIMED( "clear_pair", clear( &sp ); )
    26         REPEAT_TIMED( "pop_pair", N,
    27                 pair(_Bool, char) xp = pop( &tp );
    28                 if ( xp > maxp ) { maxp = xp; } )
    29         REPEAT_TIMED( "print_pair", N/2, print( out, valp, ":", valp, "\n" ); )
    30         fclose(out);
     23        REPEAT_TIMED( "push_pair", N, push( s, val ); )
     24        TIMED( "copy_pair", t = s; )
     25        TIMED( "clear_pair", clear( s ); )
     26        REPEAT_TIMED( "pop_pair", N, pair(_Bool, char) x = pop( t ); max = max( x, max ); )
     27        REPEAT_TIMED( "print_pair", N/2, out | val | ':' | val | endl; )
    3128}
  • doc/papers/general/evaluation/cfa-pair.c

    r094476d rcaa649b  
    11#include "cfa-pair.h"
     2#include "fstream"
    23
    3 forall(otype R, otype S 
     4forall(otype R, otype S
    45        | { int ?==?(R, R); int ?<?(R, R); int ?<?(S, S); })
    56int ?<?(pair(R, S) p, pair(R, S) q) {
     
    78}
    89
    9 forall(otype R, otype S 
     10forall(otype R, otype S
    1011        | { int ?==?(R, R); int ?<?(R, R); int ?<=?(S, S); })
    1112int ?<=?(pair(R, S) p, pair(R, S) q) {
     
    2324}
    2425
    25 forall(otype R, otype S 
     26forall(otype R, otype S
    2627        | { int ?==?(R, R); int ?>?(R, R); int ?>?(S, S); })
    2728int ?>?(pair(R, S) p, pair(R, S) q) {
     
    2930}
    3031
    31 forall(otype R, otype S 
     32forall(otype R, otype S
    3233        | { int ?==?(R, R); int ?>?(R, R); int ?>=?(S, S); })
    3334int ?>=?(pair(R, S) p, pair(R, S) q) {
    3435        return p.first > q.first || ( p.first == q.first && p.second >= q.second );
    3536}
     37
     38forall(otype R, otype S)
     39forall(dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, R ); ostype & ?|?( ostype &, S );  })
     40ostype & ?|?( ostype & os, pair(R, S) p ) {
     41        return os | '[' | p.first | ',' | p.second | ']';
     42} // ?|?
  • doc/papers/general/evaluation/cfa-pair.h

    r094476d rcaa649b  
    11#pragma once
     2
     3#include "iostream"
    24
    35forall(otype R, otype S) struct pair {
     
    2729        | { int ?==?(R, R); int ?>?(R, R); int ?>=?(S, S); })
    2830int ?>=?(pair(R, S) p, pair(R, S) q);
     31
     32forall(otype R, otype S)
     33forall(dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, pair(R, S) ); })
     34ostype & ?|?( ostype & os, pair(R, S) );
  • doc/papers/general/evaluation/cfa-stack.c

    r094476d rcaa649b  
    44forall(otype T) struct stack_node {
    55        T value;
    6         stack_node(T)* next;
     6        stack_node(T) * next;
    77};
     8forall(otype T) void ?{}( stack_node(T) & node, T value, stack_node(T) * next ) {
     9    node.value = value;
     10    node.next = next;
     11}
    812
    9 forall(otype T) void ?{}(stack(T)* s) { (&s->head){ 0 }; }
     13forall(otype T) void ?{}( stack(T) & s ) { (s.head){ 0 }; }
    1014
    11 forall(otype T) void ?{}(stack(T)* s, stack(T) t) {
    12         stack_node(T)** crnt = &s->head;
    13         for ( stack_node(T)* next = t.head; next; next = next->next ) {
    14                 *crnt = ((stack_node(T)*)malloc()){ next->value }; /***/
    15                 stack_node(T)* acrnt = *crnt;
     15forall(otype T) void ?{}( stack(T) & s, stack(T) t ) {
     16        stack_node(T) ** crnt = &s.head;
     17        for ( stack_node(T) * next = t.head; next; next = next->next ) {
     18                // *crnt = new( next->value, 0 );
     19                stack_node(T)* new_node = ((stack_node(T)*)malloc());
     20                (*new_node){ next->value }; /***/
     21                *crnt = new_node;
     22                stack_node(T) * acrnt = *crnt;
    1623                crnt = &acrnt->next;
    1724        }
     
    1926}
    2027
    21 forall(otype T) stack(T) ?=?(stack(T)* s, stack(T) t) {
    22         if ( s->head == t.head ) return *s;
    23         clear(s);
     28forall(otype T) stack(T) ?=?( stack(T) & s, stack(T) t ) {
     29        if ( s.head == t.head ) return s;
     30        clear( s );
    2431        s{ t };
    25         return *s;
     32        return s;
    2633}
    2734
    28 forall(otype T) void ^?{}(stack(T)* s) { clear(s); }
     35forall(otype T) void ^?{}( stack(T) & s) { clear( s ); }
    2936
    30 forall(otype T) _Bool empty(const stack(T)* s) { return s->head == 0; }
     37forall(otype T) _Bool empty( const stack(T) & s ) { return s.head == 0; }
    3138
    32 forall(otype T) void push(stack(T)* s, T value) {
    33         s->head = ((stack_node(T)*)malloc()){ value, s->head }; /***/
     39forall(otype T) void push( stack(T) & s, T value ) {
     40        // s.head = new( value, s.head );
     41        stack_node(T)* new_node = ((stack_node(T)*)malloc());
     42        (*new_node){ value, s.head }; /***/
     43        s.head = new_node;
    3444}
    3545
    36 forall(otype T) T pop(stack(T)* s) {
    37         stack_node(T)* n = s->head;
    38         s->head = n->next;
    39         T x = n->value;
    40         ^n{};
    41         free(n);
    42         return x;
     46forall(otype T) T pop( stack(T) & s ) {
     47        stack_node(T) * n = s.head;
     48        s.head = n->next;
     49        T v = n->value;
     50        delete( n );
     51        return v;
    4352}
    4453
    45 forall(otype T) void clear(stack(T)* s) {
    46     for ( stack_node(T)* next = s->head; next; ) {
    47                 stack_node(T)* crnt = next;
     54forall(otype T) void clear( stack(T) & s ) {
     55        for ( stack_node(T) * next = s.head; next; ) {
     56                stack_node(T) * crnt = next;
    4857                next = crnt->next;
    49                 delete(crnt);
     58                delete( crnt );
    5059        }
    51         s->head = 0;
     60        s.head = 0;
    5261}
  • doc/papers/general/evaluation/cfa-stack.h

    r094476d rcaa649b  
    33forall(otype T) struct stack_node;
    44forall(otype T) struct stack {
    5         stack_node(T)* head;
     5        stack_node(T) * head;
    66};
    77
    8 forall(otype T) void ?{}(stack(T)* s);
    9 forall(otype T) void ?{}(stack(T)* s, stack(T) t);
    10 forall(otype T) stack(T) ?=?(stack(T)* s, stack(T) t);
    11 forall(otype T) void ^?{}(stack(T)* s);
     8forall(otype T) void ?{}( stack(T) & s );
     9forall(otype T) void ?{}( stack(T) & s, stack(T) t );
     10forall(otype T) stack(T) ?=?( stack(T) & s, stack(T) t );
     11forall(otype T) void ^?{}( stack(T) & s);
    1212
    13 forall(otype T) _Bool empty(const stack(T)* s);
    14 forall(otype T) void push(stack(T)* s, T value);
    15 forall(otype T) T pop(stack(T)* s);
    16 forall(otype T) void clear(stack(T)* s);
     13forall(otype T) _Bool empty( const stack(T) & s );
     14forall(otype T) void push( stack(T) & s, T value );
     15forall(otype T) T pop( stack(T) & s );
     16forall(otype T) void clear( stack(T) & s );
Note: See TracChangeset for help on using the changeset viewer.