- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/generic_types/generic_types.tex
r17f27d40 r79b8dc3 194 194 The new constructs are empirically compared with both standard C and \CC; the results show the new design is comparable in performance. 195 195 196 197 196 \subsection{Polymorphic Functions} 198 197 \label{sec:poly-fns} 199 198 200 199 \CFA's polymorphism was originally formalized by \citet{Ditchfield92}, and first implemented by \citet{Bilson03}. 201 The signature feature of \CFA is parametric-polymorphic functions ~\citep{forceone:impl,Cormack90}where functions are generalized using a @forall@ clause (giving the language its name):200 The signature feature of \CFA is parametric-polymorphic functions where functions are generalized using a @forall@ clause (giving the language its name): 202 201 \begin{lstlisting} 203 202 `forall( otype T )` T identity( T val ) { return val; } … … 212 211 An advantage of this design is that, unlike \CC template-functions, \CFA polymorphic-functions are compatible with C \emph{separate compilation}, preventing compilation and code bloat. 213 212 214 Since bare polymorphic-types provide only a narrow set of available operations, \CFA provides a \emph{type assertion} ~\cite{alphard}mechanism to provide further type information, where type assertions may be variable or function declarations that depend on a polymorphic type-variable.213 Since bare polymorphic-types provide only a narrow set of available operations, \CFA provides a \emph{type assertion} mechanism to provide further type information, where type assertions may be variable or function declarations that depend on a polymorphic type-variable. 215 214 For example, the function @twice@ can be defined using the \CFA syntax for operator overloading: 216 215 \begin{lstlisting} … … 292 291 \smallskip\par\noindent 293 292 \lstMakeShortInline@% 294 He re, the single name @MAX@ replaces all the C type-specific names: @SHRT_MAX@, @INT_MAX@, @DBL_MAX@.293 Hence, the single name @MAX@ replaces all the C type-specific names: @SHRT_MAX@, @INT_MAX@, @DBL_MAX@. 295 294 As well, restricted constant overloading is allowed for the values @0@ and @1@, which have special status in C, \eg the value @0@ is both an integer and a pointer literal, so its meaning depends on context. 296 295 In addition, several operations are defined in terms values @0@ and @1@, \eg: … … 299 298 if (x) x++ $\C{// if (x != 0) x += 1;}$ 300 299 \end{lstlisting} 301 Every if and iterationstatement in C compares the condition with @0@, and every increment and decrement operator is semantically equivalent to adding or subtracting the value @1@ and storing the result.300 Every if statement in C compares the condition with @0@, and every increment and decrement operator is semantically equivalent to adding or subtracting the value @1@ and storing the result. 302 301 Due to these rewrite rules, the values @0@ and @1@ have the types @zero_t@ and @one_t@ in \CFA, which allows overloading various operations for new types that seamlessly connect to all special @0@ and @1@ contexts. 303 302 The types @zero_t@ and @one_t@ have special built in implicit conversions to the various integral types, and a conversion to pointer types for @0@, which allows standard C code involving @0@ and @1@ to work as normal. … … 320 319 \end{lstlisting} 321 320 322 In fact, the set of @summable@ trait operators is incomplete, as it is missing assignment for type @T@, but @otype@ is syntactic sugar for the following implicit trait:321 In fact, the set of trait operators is incomplete, as there is no assignment requirement for type @T@, but @otype@ is syntactic sugar for the following implicit trait: 323 322 \begin{lstlisting} 324 323 trait otype( dtype T | sized(T) ) { // sized is a pseudo-trait for types with known size and alignment … … 516 515 [ int, int ] div( int num, int den ); $\C{// return two integers}$ 517 516 [ double, double ] div( double num, double den ); $\C{// return two doubles}$ 518 int q, r; $\C{// overload edvariable names}$517 int q, r; $\C{// overload variable names}$ 519 518 double q, r; 520 519 [ q, r ] = div( 13, 5 ); $\C{// select appropriate div and q, r}$ 521 [ q, r ] = div( 13.5, 5.2 ); $\C{// assign into tuple}$520 [ q, r ] = div( 13.5, 5.2 ); 522 521 \end{lstlisting} 523 522 Clearly, this approach is straightforward to understand and use; 524 523 therefore, why do few programming languages support this obvious feature or provide it awkwardly? 525 524 The answer is that there are complex consequences that cascade through multiple aspects of the language, especially the type-system. 526 This section show these consequences and how \CFA handlesthem.525 This section show these consequences and how \CFA deals with them. 527 526 528 527 … … 537 536 printf( "%d %d\n", div( 13, 5 ) ); $\C{// return values seperated into arguments}$ 538 537 \end{lstlisting} 539 Here, the values returned by @div@ are composed with the call to @printf@ by flattening the tuple into separate arguments.538 Here, the values returned by @div@ are composed with the call to @printf@. 540 539 However, the \CFA type-system must support significantly more complex composition: 541 540 \begin{lstlisting} … … 553 552 554 553 An important observation from function composition is that new variable names are not required to initialize parameters from an MRVF. 555 \CFA also allows declaration of tuple variables that can be initialized from an MRVF, since it can be awkward to declare multiple variables of different types, \eg: 554 \CFA also allows declaration of tuple variables that can be initialized from an MRVF, since it can be awkward to declare multiple variables of different types. 555 As a consequence, \CFA allows declaration of \emph{tuple variables} that can be initialized from an MRVF, \eg: 556 556 \begin{lstlisting} 557 557 [ int, int ] qr = div( 13, 5 ); $\C{// tuple-variable declaration and initialization}$ … … 665 665 x.[0, 1] = x.[1, 0]; $\C[1in]{// rearrange: [x.0, x.1] = [x.1, x.0]}$ 666 666 f( x.[0, 3] ); $\C{// drop: f(x.0, x.3)}\CRT{}$ 667 [int, int, int] y = x.[2, 0, 2]; // duplicate: [y.0, y.1, y.2] = [x.2, x.0.x.2] 667 [int, int, int] y = x.[2, 0, 2]; // duplicate: [y.0, y.1, y.2] = [x.2, x.0. 668 x.2] 668 669 \end{lstlisting} 669 670 \end{tabular} … … 953 954 Instead, the presented benchmarks show the costs of idiomatic use of each language's features to examine common usage. 954 955 Figure~\ref{fig:MicroBenchmark} 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}. 955 The benchmark tests are similar for C and \CC. 956 The experiment uses element types @int@ and @pair( _Bool, char)@, and push $N=40M$ elements on a generic stack, copy the stack, clear one of the stacks, find the maximum value in the other stack, and print $N$ constant values. 957 958 The structure of each benchmark implemented is: C with @void *@-based polymorphism, \CFA with the different presented features, \CC with templates, and \CC using only class inheritance for polymorphism, called \CCV. 956 The tests are similar for C and \CC. 957 The first two experiments use element types @int@ and @pair( _Bool, char)@, and push $N=40M$ elements on a generic stack, copy the stack, clear one of the stacks, and find the maximum value in the other stack. 958 The last experiment creates a file and prints $N=40M$ elements of type @int@ and @pair( _Bool, char)@ using a variadic print. 959 960 The structure of each implemented is: C with @void *@-based polymorphism, \CFA with the different presented features, \CC with templates, and \CC using only class inheritance for polymorphism, called \CCV. 959 961 The \CCV variant illustrates an alternative object-oriented idiom where all objects inherit from a base @object@ class, mimicking a Java-like interface; 960 962 hence runtime checks are necessary to safely down-cast objects. … … 962 964 For the print benchmark, idiomatic printing is used: the C and \CFA variants used @cstdio.h@, while the \CC and \CCV variants used @iostream@. 963 965 Preliminary tests show the difference has little runtime effect. 964 %Finally, the C @rand@ function is used generate random numbers.966 Finally, the C @rand@ function is used generate random numbers. 965 967 966 968 \begin{figure} 967 969 \begin{lstlisting}[xleftmargin=3\parindentlnth,aboveskip=0pt,belowskip=0pt,numbers=left,numberstyle=\tt\small,numberblanklines=false] 968 970 int main( int argc, char *argv[] ) { 971 int max = 0; 972 stack(int) s, t; 973 REPEAT_TIMED( "push_int", push( &s, 42 ); ) 974 TIMED( "copy_int", t = s; ) 975 TIMED( "clear_int", clear( &s ); ) 976 REPEAT_TIMED( "pop_int", max = max( max, pop( &t ) ); ) 977 978 stack(pair(_Bool, char)) s1, t1; 979 pair(_Bool, char) max = { (_Bool)0, '\0' }; 980 REPEAT_TIMED( "push_pair", push( &s1, (pair(_Bool, char)){ (_Bool)0, 'a' } ); ) 981 TIMED( "copy_pair", t1 = s1; ) 982 TIMED( "clear_pair", clear( &s1 ); ) 983 REPEAT_TIMED( "pop_pair", max = max( max, pop( &t1 ) ); ) 984 969 985 FILE * out = fopen( "cfa-out.txt", "w" ); 970 int max = 0, vali = 42; 971 stack(int) si, ti; 972 973 REPEAT_TIMED( "push_int", push( &si, vali ); ) 974 TIMED( "copy_int", ti = si; ) 975 TIMED( "clear_int", clear( &si ); ) 976 REPEAT_TIMED( "pop_int", max = max( max, pop( &ti ) ); ) 977 REPEAT_TIMED( "print_int", print( out, vali, ":", vali, "\n" ); ) 978 979 pair(_Bool, char) maxp = { (_Bool)0, '\0' }, valp = { (_Bool)0, 'a' }; 980 stack(pair(_Bool, char)) sp, tp; 981 982 REPEAT_TIMED( "push_pair", push( &sp, valp ); ) 983 TIMED( "copy_pair", tp = sp; ) 984 TIMED( "clear_pair", clear( &sp ); ) 985 REPEAT_TIMED( "pop_pair", maxp = max( maxp, pop( &tp ) ); ) 986 REPEAT_TIMED( "print_pair", print( out, valp, ":", valp, "\n" ); ) 986 REPEAT_TIMED( "print_int", print( out, 42, ":", 42, "\n" ); ) 987 REPEAT_TIMED( "print_pair", print( out, (pair(_Bool, char)){ (_Bool)0, 'a' }, ":", 988 (pair(_Bool, char)){ (_Bool)0, 'a' }, "\n" ); ) 987 989 fclose(out); 988 990 } 989 991 \end{lstlisting} 990 \caption{ \CFAMicro-Benchmark}992 \caption{Micro-Benchmark} 991 993 \label{fig:MicroBenchmark} 992 994 \end{figure} … … 1004 1006 \newcommand{\CT}[1]{\multicolumn{1}{c}{#1}} 1005 1007 \begin{tabular}{r|rrrr} 1006 & \CT{C} & \CT{\CFA} & \CT{\CC} & \CT{\CCV}\\ \hline1007 maximum memory usage (MB) & 10001 & 2501 & 2503 & 11253\\1008 source code size (lines) & 301 & 224 & 188 &437 \\1009 redundant type annotations (lines) & 46 & 3 & 2 & 1010 binary size (KB) & 18 & 234 & 18 &42 \\1008 & \CT{C} & \CT{\CFA} & \CT{\CC} & \CT{\CCV} \\ \hline 1009 maximum memory usage (MB) & 10001 & 2501 & 2503 & 11253 \\ 1010 source code size (lines) & 301 & 224 & 188 & 437 \\ 1011 redundant type annotations (lines) & 46 & 3 & 2 & 15 \\ 1012 binary size (KB) & 18 & 234 & 18 & 42 \\ 1011 1013 \end{tabular} 1012 1014 \end{table} … … 1097 1099 \section{Conclusion \& Future Work} 1098 1100 1099 The \CFA goal is to provide an evolutionary pathway for large C development-environments to be more productive and safer, while respecting the talent and skill of C programmers.1100 While other programming languages purport to be a better C, they are in fact new and interesting languages in their own right, but not C extensions.1101 The purpose of this paper is to introduce \CFA, and showcase two language features that illustrate the \CFA type-system and approaches taken to achieve the evolutionary goal.1102 The contributions are a powerful type-system using parametric polymorphism and overloading, generic types, and tuples, which all have complex interactions.1103 The work is a challenging design, engineering, and implementation exercise.1104 On the surface, the project may appear as a rehash of similar mechanisms in \CC.1105 However, every \CFA feature is different than its \CC counterpart, often with extended functionality, better integration with C and its programmers, and always supporting separate compilation.1106 All of these new features are being used by the \CFA development-team to build the \CFA runtime system.1107 Finally, we demonstrate that \CFA performance for some idiomtic cases is better than C and close to \CC, showing the design is competitive.1108 1109 1101 There is ongoing work on a wide range of \CFA feature extensions, including reference types, exceptions, and concurrent programming primitives. 1110 1102 In addition to this work, there are some interesting future directions the polymorphism design could take. … … 1115 1107 These approaches are not mutually exclusive, and would allow these performance optimizations to be applied only where most useful to increase performance, without suffering the code bloat or loss of generality of a template expansion approach where it is unnecessary. 1116 1108 1109 In conclusion, the authors' design for generic types and tuples, unlike those available in existing work, is both reusable and type-checked, while still supporting a full range of C features, including separately-compiled modules. 1110 We have experimentally validated the performance of our design against both \CC and standard C, showing it is comparable to both, and in some cases better. 1111 1117 1112 1118 1113 \begin{acks}
Note: See TracChangeset
for help on using the changeset viewer.