Changeset 0eb18557 for doc/rob_thesis/intro.tex
- Timestamp:
- Apr 12, 2017, 3:54:28 PM (7 years ago)
- 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:
- e869e434
- Parents:
- eaa2f3a1
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/rob_thesis/intro.tex
reaa2f3a1 r0eb18557 16 16 Therefore, these design principles must be kept in mind throughout the design and development of new language features. 17 17 In order to appeal to existing C programmers, great care must be taken to ensure that new features naturally feel like C. 18 These goals ensure existing C code-bases can be converted to \CFA incrementally with minimal effort, and C programmers can productively generate \CFA code without training beyond the features being used. 19 Unfortunately, \CC is actively diverging from C, so incremental additions require significant effort and training, coupled with multiple legacy design-choices that cannot be updated. 20 18 21 The remainder of this section describes some of the important new features that currently exist in \CFA, to give the reader the necessary context in which the new features presented in this thesis must dovetail. 19 22 … … 53 56 \end{cfacode} 54 57 Compound literals create an unnamed object, and result in an lvalue, so it is legal to assign a value into a compound literal or to take its address \cite[p.~86]{C11}. 55 Syntactically, compound literals look like a cast operator followed by a brace-enclosed initializer, but semantically are different from a C cast, which only applies basic conversions and is never an lvalue.58 Syntactically, compound literals look like a cast operator followed by a brace-enclosed initializer, but semantically are different from a C cast, which only applies basic conversions and coercions and is never an lvalue. 56 59 57 60 \subsection{Overloading} … … 59 62 Overloading is the ability to specify multiple entities with the same name. 60 63 The most common form of overloading is function overloading, wherein multiple functions can be defined with the same name, but with different signatures. 61 Like in \CC, \CFA allows overloading based both on the number of parameters and on the types of parameters. 64 C provides a small amount of built-in overloading, \eg + is overloaded for the basic types. 65 Like in \CC, \CFA allows user-defined overloading based both on the number of parameters and on the types of parameters. 62 66 \begin{cfacode} 63 67 void f(void); // (1) … … 92 96 There are times when a function should logically return multiple values. 93 97 Since a function in standard C can only return a single value, a programmer must either take in additional return values by address, or the function's designer must create a wrapper structure to package multiple return-values. 98 For example, the first approach: 94 99 \begin{cfacode} 95 100 int f(int * ret) { // returns a value through parameter ret … … 101 106 int res1 = g(&res2); // explicitly pass storage 102 107 \end{cfacode} 103 The former solutionis awkward because it requires the caller to explicitly allocate memory for $n$ result variables, even if they are only temporary values used as a subexpression, or even not used at all.104 The latterapproach:108 is awkward because it requires the caller to explicitly allocate memory for $n$ result variables, even if they are only temporary values used as a subexpression, or even not used at all. 109 The second approach: 105 110 \begin{cfacode} 106 111 struct A { … … 113 118 ... res3.x ... res3.y ... // use result values 114 119 \end{cfacode} 115 requires the callerto either learn the field names of the structure or learn the names of helper routines to access the individual return values.116 Both solutions are syntactically unnatural.120 is awkward because the caller has to either learn the field names of the structure or learn the names of helper routines to access the individual return values. 121 Both approaches are syntactically unnatural. 117 122 118 123 In \CFA, it is possible to directly declare a function returning multiple values. … … 165 170 \begin{cfacode} 166 171 struct A { int i; }; 167 int ?+?(A x, A y); 172 int ?+?(A x, A y); // '?'s represent operands 168 173 bool ?<?(A x, A y); 169 174 \end{cfacode} 170 175 Notably, the only difference is syntax. 171 176 Most of the operators supported by \CC for operator overloading are also supported in \CFA. 172 Of notable exception are the logical operators ( e.g. @||@), the sequence operator (i.e. @,@), and the member-access operators (e.g.@.@ and \lstinline{->}).177 Of notable exception are the logical operators (\eg @||@), the sequence operator (\ie @,@), and the member-access operators (\eg @.@ and \lstinline{->}). 173 178 174 179 Finally, \CFA also permits overloading variable identifiers. … … 243 248 template<typename T> 244 249 T sum(T *arr, int n) { 245 T t; 250 T t; // default construct => 0 246 251 for (; n > 0; n--) t += arr[n-1]; 247 252 return t; … … 261 266 \end{cfacode} 262 267 The first thing to note here is that immediately following the declaration of @otype T@ is a list of \emph{type assertions} that specify restrictions on acceptable choices of @T@. 263 In particular, the assertions above specify that there must be a an assignment from \zero to @T@ and an addition assignment operator from @T@ to @T@.268 In particular, the assertions above specify that there must be an assignment from \zero to @T@ and an addition assignment operator from @T@ to @T@. 264 269 The existence of an assignment operator from @T@ to @T@ and the ability to create an object of type @T@ are assumed implicitly by declaring @T@ with the @otype@ type-class. 265 270 In addition to @otype@, there are currently two other type-classes. … … 281 286 A major difference between the approaches of \CC and \CFA to polymorphism is that the set of assumed properties for a type is \emph{explicit} in \CFA. 282 287 One of the major limiting factors of \CC's approach is that templates cannot be separately compiled. 283 In contrast, the explicit nature of assertions allows \CFA's polymorphic functions to be separately compiled. 288 In contrast, the explicit nature of assertions allows \CFA's polymorphic functions to be separately compiled, as the function prototype states all necessary requirements separate from the implementation. 289 For example, the prototype for the previous sum function is 290 \begin{cfacode} 291 forall(otype T | **R**{ T ?=?(T *, zero_t); T ?+=?(T *, T); }**R**) 292 T sum(T *arr, int n); 293 \end{cfacode} 294 With this prototype, a caller in another translation unit knows all of the constraints on @T@, and thus knows all of the operations that need to be made available to @sum@. 284 295 285 296 In \CFA, a set of assertions can be factored into a \emph{trait}. … … 296 307 This capability allows specifying the same set of assertions in multiple locations, without the repetition and likelihood of mistakes that come with manually writing them out for each function declaration. 297 308 298 An interesting application of return-type resolution and polymorphism is with type-safe@malloc@.309 An interesting application of return-type resolution and polymorphism is a type-safe version of @malloc@. 299 310 \begin{cfacode} 300 311 forall(dtype T | sized(T)) … … 316 327 317 328 In object-oriented programming languages, type invariants are typically established in a constructor and maintained throughout the object's lifetime. 318 These assertions are typically achieved through a combination of access 329 These assertions are typically achieved through a combination of access-control modifiers and a restricted interface. 319 330 Typically, data which requires the maintenance of an invariant is hidden from external sources using the \emph{private} modifier, which restricts reads and writes to a select set of trusted routines, including member functions. 320 331 It is these trusted routines that perform all modifications to internal data in a way that is consistent with the invariant, by ensuring that the invariant holds true at the end of the routine call. … … 388 399 In other languages, a hybrid situation exists where resources escape the allocation block, but ownership is precisely controlled by the language. 389 400 This pattern requires a strict interface and protocol for a data structure, consisting of a pre-initialization and a post-termination call, and all intervening access is done via interface routines. 390 This kind of encapsulation is popular in object-oriented programming languages, and like the stack, it takes care of a significant portion of resource 401 This kind of encapsulation is popular in object-oriented programming languages, and like the stack, it takes care of a significant portion of resource-management cases. 391 402 392 403 For example, \CC directly supports this pattern through class types and an idiom known as RAII \footnote{Resource Acquisition is Initialization} by means of constructors and destructors. … … 399 410 In the context of \CFA, a non-trivial constructor is either a user defined constructor or an auto-generated constructor that calls a non-trivial constructor. 400 411 401 For the remaining resource ownership cases, programmer must follow a brittle, explicit protocol for freeing resources or an implicit protocol implemented viathe programming language.412 For the remaining resource ownership cases, a programmer must follow a brittle, explicit protocol for freeing resources or an implicit protocol enforced by the programming language. 402 413 403 414 In garbage collected languages, such as Java, resources are largely managed by the garbage collector. 404 Still, garbage collectors aretypically focus only on memory management.415 Still, garbage collectors typically focus only on memory management. 405 416 There are many kinds of resources that the garbage collector does not understand, such as sockets, open files, and database connections. 406 417 In particular, Java supports \emph{finalizers}, which are similar to destructors. 407 Sadly, finalizers are only guaranteed to be called before an object is reclaimed by the garbage collector \cite[p.~373]{Java8}, which may not happen if memory use is not contentious.418 Unfortunately, finalizers are only guaranteed to be called before an object is reclaimed by the garbage collector \cite[p.~373]{Java8}, which may not happen if memory use is not contentious. 408 419 Due to operating-system resource-limits, this is unacceptable for many long running programs. 409 420 Instead, the paradigm in Java requires programmers to manually keep track of all resources \emph{except} memory, leading many novices and experts alike to forget to close files, etc. … … 450 461 \end{javacode} 451 462 Variables declared as part of a try-with-resources statement must conform to the @AutoClosable@ interface, and the compiler implicitly calls @close@ on each of the variables at the end of the block. 452 Depending on when the exception is raised, both @out@ and @log@ are null, @log@ is null, or both are non-null, therefore, the cleanup for these variables at the end is a ppropriately guarded and conditionally executed to prevent null-pointer exceptions.463 Depending on when the exception is raised, both @out@ and @log@ are null, @log@ is null, or both are non-null, therefore, the cleanup for these variables at the end is automatically guarded and conditionally executed to prevent null-pointer exceptions. 453 464 454 465 While Rust \cite{Rust} does not enforce the use of a garbage collector, it does provide a manual memory management environment, with a strict ownership model that automatically frees allocated memory and prevents common memory management errors. … … 486 497 There is no runtime cost imposed on these restrictions, since they are enforced at compile-time. 487 498 488 Rust provides RAII through the @Drop@ trait, allowing arbitrary code to execute when the object goes out of scope, allowing Rust programs to automatically clean up auxiliary resourcesmuch like a \CC program.499 Rust provides RAII through the @Drop@ trait, allowing arbitrary code to execute when the object goes out of scope, providing automatic clean up of auxiliary resources, much like a \CC program. 489 500 \begin{rustcode} 490 501 struct S { … … 493 504 494 505 impl Drop for S { // RAII for S 495 fn drop(&mut self) { 506 fn drop(&mut self) { // destructor 496 507 println!("dropped {}", self.name); 497 508 } … … 558 569 tuple<int, int, int> triple(10, 20, 30); 559 570 auto & [t1, t2, t3] = triple; 560 t2 = 0; // changes triple571 t2 = 0; // changes middle element of triple 561 572 562 573 struct S { int x; double y; }; … … 564 575 auto [x, y] = s; // unpack s 565 576 \end{cppcode} 566 Structured bindings allow unpacking any struct with all public non-static data members into fresh local variables.577 Structured bindings allow unpacking any structure with all public non-static data members into fresh local variables. 567 578 The use of @&@ allows declaring new variables as references, which is something that cannot be done with @std::tie@, since \CC references do not support rebinding. 568 579 This extension requires the use of @auto@ to infer the types of the new variables, so complicated expressions with a non-obvious type must be documented with some other mechanism. 569 580 Furthermore, structured bindings are not a full replacement for @std::tie@, as it always declares new variables. 570 581 571 Like \CC, D provides tuples through a library variadic template struct.582 Like \CC, D provides tuples through a library variadic-template structure. 572 583 In D, it is possible to name the fields of a tuple type, which creates a distinct type. 573 584 % http://dlang.org/phobos/std_typecons.html … … 600 611 \end{smlcode} 601 612 Here, the function @binco@ appears to take 2 arguments, but it actually takes a single argument which is implicitly decomposed via pattern matching. 602 Tuples are a foundational tool in SML, allowing the creation of arbitrarily complex structured datatypes.613 Tuples are a foundational tool in SML, allowing the creation of arbitrarily-complex structured data-types. 603 614 604 615 Scala, like \CC, provides tuple types through the standard library \cite{Scala}. … … 653 664 Since the variadic arguments are untyped, it is up to the function to interpret any data that is passed in. 654 665 Additionally, the interface to manipulate @va_list@ objects is essentially limited to advancing to the next argument, without any built-in facility to determine when the last argument is read. 655 This requires the use of an \emph{argument descriptor} to pass information to the function about the structure of the argument list, including the number of arguments and their types.666 This limitation requires the use of an \emph{argument descriptor} to pass information to the function about the structure of the argument list, including the number of arguments and their types. 656 667 The format string in @printf@ is one such example of an argument descriptor. 657 668 \begin{cfacode}
Note: See TracChangeset
for help on using the changeset viewer.