Changes in doc/papers/general/Paper.tex [d52a55b:aa5fdac]
- File:
-
- 1 edited
-
doc/papers/general/Paper.tex (modified) (24 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/general/Paper.tex
rd52a55b raa5fdac 228 228 Nevertheless, C, first standardized over thirty years ago, lacks many features that make programming in more modern languages safer and more productive. 229 229 230 \CFA (pronounced ``C-for-all'', and written \CFA or Cforall) is an evolutionary extension of the C programming language that a dds modern language-features to C, while maintaining both source and runtime compatibility with C and a familiar programming model for programmers.230 \CFA (pronounced ``C-for-all'', and written \CFA or Cforall) is an evolutionary extension of the C programming language that aims to add modern language features to C, while maintaining both source and runtime compatibility with C and a familiar programming model for programmers. 231 231 The four key design goals for \CFA~\cite{Bilson03} are: 232 232 (1) The behaviour of standard C code must remain the same when translated by a \CFA compiler as when translated by a C compiler; … … 237 237 \CC is used similarly, but has the disadvantages of multiple legacy design-choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project. 238 238 239 All languages features discussed in this paper are working, except some advanced exception-handling features.240 Not discussed in this paper are the integrated concurrency-constructs and user-level threading-library~\cite{Delisle18}.241 239 \CFA is an \emph{open-source} project implemented as an 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). 242 240 Ultimately, a compiler is necessary for advanced features and optimal performance. 243 % @plg2[9]% cd cfa-cc/src; cloc ArgTweak CodeGen CodeTools Common Concurrency ControlStruct Designators GenPoly InitTweak MakeLibCfa.cc MakeLibCfa.h Parser ResolvExpr SymTab SynTree Tuples driver prelude main.cc 244 % ------------------------------------------------------------------------------- 245 % Language files blank comment code 246 % ------------------------------------------------------------------------------- 247 % C++ 108 5420 5232 34961 248 % C/C++ Header 86 2379 2450 8464 249 % Teamcenter def 2 115 65 1387 250 % make 5 168 87 1052 251 % C 20 109 403 488 252 % awk 1 12 26 121 253 % sed 1 0 0 6 254 % ------------------------------------------------------------------------------- 255 % SUM: 223 8203 8263 46479 256 % ------------------------------------------------------------------------------- 257 The \CFA translator is 200+ files and 46,000+ lines of code written in C/\CC. 258 Starting with a translator versus a compiler makes it easier and faster to generate and debug C object-code rather than intermediate, assembler or machine code. 259 The translator design is based on the \emph{visitor pattern}, allowing multiple passes over the abstract code-tree, which works well for incrementally adding new feature through additional visitor passes. 260 At the heart of the translator is the type resolver, which handles the polymorphic routine/type overload-resolution. 261 % @plg2[8]% cd cfa-cc/src; cloc libcfa 262 % ------------------------------------------------------------------------------- 263 % Language files blank comment code 264 % ------------------------------------------------------------------------------- 265 % C 35 1256 1240 9116 266 % C/C++ Header 54 358 1106 1198 267 % make 2 201 325 1167 268 % C++ 3 18 17 124 269 % Assembly 3 56 97 111 270 % Bourne Shell 2 2 0 25 271 % awk 1 4 0 22 272 % ------------------------------------------------------------------------------- 273 % SUM: 100 1895 2785 11763 274 % ------------------------------------------------------------------------------- 275 The \CFA runtime system is 100+ files and 11,000+ lines of code, written in \CFA. 276 Currently, the \CFA runtime is the largest \emph{user} of \CFA providing a vehicle to test the language features and implementation. 277 % @plg2[6]% cd cfa-cc/src; cloc tests examples benchmark 278 % ------------------------------------------------------------------------------- 279 % Language files blank comment code 280 % ------------------------------------------------------------------------------- 281 % C 237 12260 2869 23286 282 % make 8 464 245 2838 283 % C/C++ Header 22 225 175 785 284 % Python 5 131 93 420 285 % C++ 10 48 5 201 286 % Lua 2 31 4 126 287 % Java 4 5 0 80 288 % Go 2 11 9 40 289 % ------------------------------------------------------------------------------- 290 % SUM: 290 13175 3400 27776 291 % ------------------------------------------------------------------------------- 292 The \CFA tests are 290+ files and 27,000+ lines of code. 293 The tests illustrate syntactic and semantic features in \CFA, plus a growing number of runtime benchmarks. 294 The tests check for correctness and are used for daily regression testing of commits (3800+). 241 All features discussed in this paper are working, unless otherwise stated as under construction. 295 242 296 243 Finally, it is impossible to describe a programming language without usages before definitions. … … 313 260 There are only two hard things in Computer Science: cache invalidation and \emph{naming things} -- Phil Karlton 314 261 \end{quote} 315 \vspace{-10pt}316 262 C 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. 317 263 \CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable; … … 408 354 409 355 \CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations (see Section~\ref{sec:libraries}). 410 For example, it is possible to write a type-safe \CFA wrapper @malloc@ based on the C @malloc@ , where the return type supplies the type/size of the allocation, which is impossible in most type systems.356 For example, it is possible to write a type-safe \CFA wrapper @malloc@ based on the C @malloc@: 411 357 \begin{cfa} 412 358 forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); } 413 // select type and size from left-hand side 414 int * ip = malloc(); double * dp = malloc(); struct S {...} * sp = malloc(); 415 \end{cfa} 359 int * ip = malloc(); $\C{// select type and size from left-hand side}$ 360 double * dp = malloc(); 361 struct S {...} * sp = malloc(); 362 \end{cfa} 363 where the return type supplies the type/size of the allocation, which is impossible in most type systems. 416 364 417 365 Call-site inferencing and nested functions provide a localized form of inheritance. … … 425 373 } 426 374 \end{cfa} 427 The local version of @?<?@ performs @?>?@ overridingthe built-in @?<?@ so it is passed to @qsort@.375 Within the block, the nested version of @?<?@ performs @?>?@ and this local version overrides the built-in @?<?@ so it is passed to @qsort@. 428 376 Hence, programmers can easily form local environments, adding and modifying appropriate functions, to maximize reuse of other existing functions and types. 429 377 … … 434 382 inline { $\C{// nested distribution block, add forall/inline to declarations}$ 435 383 void push( stack(`T`) & s, `T` value ) ... $\C{// generic operations}$ 384 T pop( stack(`T`) & s ) ... 436 385 } 437 386 } … … 439 388 440 389 441 \vspace*{-2pt}442 390 \subsection{Traits} 443 391 444 392 \CFA provides \newterm{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration: 445 446 393 \begin{cquote} 447 394 \lstDeleteShortInline@% … … 515 462 516 463 517 \vspace*{-2pt}518 464 \section{Generic Types} 519 465 … … 528 474 529 475 \CC, Java, and other languages use \newterm{generic types} to produce type-safe abstract data-types. 530 \CFA generic typesintegrate efficiently and naturally with the existing polymorphic functions, while retaining backwards compatibility with C and providing separate compilation.476 \CFA also implements generic types that integrate efficiently and naturally with the existing polymorphic functions, while retaining backwards compatibility with C and providing separate compilation. 531 477 However, for known concrete parameters, the generic-type definition can be inlined, like \CC templates. 532 478 … … 534 480 \begin{cquote} 535 481 \lstDeleteShortInline@% 536 \begin{tabular}{@{}l |@{\hspace{2\parindentlnth}}l@{}}482 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 537 483 \begin{cfa} 538 484 forall( otype R, otype S ) struct pair { … … 1427 1373 resume( $\emph{alternate-stack}$ ) 1428 1374 \end{cfa} 1429 These overloads of @resume@ raise the specified exception or the currently propagating exception (reresume) at another \CFA coroutine or task ~\cite{Delisle18}.1375 These overloads of @resume@ raise the specified exception or the currently propagating exception (reresume) at another \CFA coroutine or task\footnote{\CFA coroutine and concurrency features are discussed in a separately submitted paper.}~\cite{Delisle18}. 1430 1376 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 handler returns. 1431 1377 … … 2094 2040 2095 2041 2096 \begin{comment}2097 2042 \subsection{Integral Suffixes} 2098 2043 … … 2128 2073 \lstMakeShortInline@% 2129 2074 \end{cquote} 2130 \end{comment}2131 2075 2132 2076 … … 2700 2644 Figure~\ref{fig:eval} and Table~\ref{tab:eval} show the results of running the benchmark in Figure~\ref{fig:BenchmarkTest} and its C, \CC, and \CCV equivalents. 2701 2645 The graph plots the median of 5 consecutive runs of each program, with an initial warm-up run omitted. 2702 All code is compiled at \texttt{-O2} by gcc or g++ 6. 4.0, with all \CC code compiled as \CCfourteen.2646 All code is compiled at \texttt{-O2} by gcc or g++ 6.3.0, with all \CC code compiled as \CCfourteen. 2703 2647 The benchmarks are run on an Ubuntu 16.04 workstation with 16 GB of RAM and a 6-core AMD FX-6300 CPU with 3.5 GHz maximum clock frequency. 2704 2648 … … 2718 2662 & \CT{C} & \CT{\CFA} & \CT{\CC} & \CT{\CCV} \\ \hline 2719 2663 maximum memory usage (MB) & 10,001 & 2,502 & 2,503 & 11,253 \\ 2720 source code size (lines) & 201 & 191 & 125 & 294\\2664 source code size (lines) & 196 & 186 & 125 & 290 \\ 2721 2665 redundant type annotations (lines) & 27 & 0 & 2 & 16 \\ 2722 2666 binary size (KB) & 14 & 257 & 14 & 37 \\ … … 2821 2765 data-parallel features have not yet been added to \CFA, but are easily incorporated within its design, while concurrency primitives similar to those in $\mu$\CC have already been added~\cite{Delisle18}. 2822 2766 Finally, CCured~\cite{Necula02} and Ironclad \CC~\cite{DeLozier13} attempt to provide a more memory-safe C by annotating pointer types with garbage collection information; type-checked polymorphism in \CFA covers several of C's memory-safety issues, but more aggressive approaches such as annotating all pointer types with their nullability or requiring runtime garbage collection are contradictory to \CFA's backwards compatibility goals. 2767 2768 2769 \begin{comment} 2770 \subsection{Control Structures / Declarations / Literals} 2771 2772 Java has default fall through like C/\CC. 2773 Pascal/Ada/Go/Rust do not have default fall through. 2774 \Csharp does not have fall through but still requires a break. 2775 Python uses dictionary mapping. \\ 2776 \CFA choose is like Rust match. 2777 2778 Java has labelled break/continue. \\ 2779 Languages with and without exception handling. 2780 2781 Alternative C declarations. \\ 2782 Different references \\ 2783 Constructors/destructors 2784 2785 0/1 Literals \\ 2786 user defined: D, Objective-C 2787 \end{comment} 2823 2788 2824 2789 … … 2910 2875 } 2911 2876 _Bool stack_empty( const stack * s ) { 2912 return s->head == NULL;2877 return s->head == NULL; 2913 2878 } 2914 2879 void push_stack( stack * s, void * v ) { 2915 node * n = malloc( sizeof(node)); /***/2880 node * n = malloc(sizeof(node)); /***/ 2916 2881 *n = (node){ v, s->head }; /***/ 2917 2882 s->head = n; … … 2943 2908 }; 2944 2909 struct stack { node(T) * head; }; 2945 void ?{}( stack(T) & s, stack(T) t ) { // copy 2910 void ?{}( stack(T) & s ) { (s.head){ 0 }; } 2911 void ?{}( stack(T) & s, stack(T) t ) { 2946 2912 node(T) ** cr = &s.head; 2947 2913 for ( node(T) * nx = t.head; nx; nx = nx->next ) { … … 2957 2923 nx = cr->next; 2958 2924 ^(*cr){}; 2959 free( cr);2925 free(cr); 2960 2926 } 2961 2927 head = 0; 2962 2928 } 2963 2964 2929 \end{cfa} 2965 2930 & 2966 2931 \begin{cfa}[xleftmargin=0pt,aboveskip=0pt,belowskip=0pt] 2967 void ?{}( stack(T) & s ) { (s.head){ 0 }; }2968 2932 void ^?{}( stack(T) & s) { clear( s ); } 2969 2933 stack(T) ?=?( stack(T) & s, stack(T) t ) { … … 2990 2954 } 2991 2955 } 2956 2992 2957 \end{cfa} 2993 2958 \end{tabular} … … 3038 3003 return *this; 3039 3004 } 3040 bool empty() const { 3041 return head == nullptr; 3042 } 3005 bool empty() const { return head == nullptr; } 3043 3006 void push( const T & value ) { 3044 3007 head = new node{ value, head }; /***/ … … 3052 3015 } 3053 3016 }; 3017 3018 3054 3019 3055 3020 \end{cfa} … … 3101 3066 return *this; 3102 3067 } 3103 bool empty() const { 3104 return head == nullptr; 3105 } 3068 bool empty() const { return head == nullptr; } 3106 3069 void push( const object & value ) { 3107 3070 head = new node{ value, head }; /***/ … … 3116 3079 }; 3117 3080 3081 3082 3118 3083 \end{cfa} 3119 3084 \end{tabular}
Note:
See TracChangeset
for help on using the changeset viewer.