# Changeset 91a950c

Ignore:
Timestamp:
Sep 17, 2018, 4:21:10 PM (3 years ago)
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer
Children:
4075228, 4c42a5f, 72b0573, d21d01e5
Parents:
f9c7d27
Message:

Finish first draft of background chapter

File:
1 edited

### Legend:

Unmodified
 rf9c7d27 Together, \CFA{}'s backward-compatibility with C and the inclusion of this operator overloading feature imply that \CFA{} must select among function overloads using a method compatible with C's usual arithmetic conversions''\cit{}, so as to present user programmers with only a single set of overloading rules. \subsection{Polymorphic Functions} \subsubsection{Special Literal Types} Literal !0! is also used polymorphically in C; it may be either integer zero or the null value of any pointer type. \CFA{} provides a special type for the !0! literal, !zero_t!, so that users can define a zero value for their own types without being forced to create a conversion from an integer or pointer type (though \CFA{} also includes implicit conversions from !zero_t! to the integer and pointer types for backward compatibility). According to the C standard\cit{}, !0! is the only false value; any value that compares equal to zero is false, while any value that does not is true. By this rule, boolean contexts such as !if ( x )! can always be equivalently rewritten as \lstinline{if ( (x) != 0 )}. \CFACC{} applies this rewriting in all boolean contexts, so any type !T! can be made truthy'' (that is, given a boolean interpretation) in \CFA{} by defining an operator overload \lstinline{int ?!=?(T, zero_t)}; unlike \CC{} prior to the addition of explicit casts in \CCeleven{}, this design does not add comparability or convertablity to arbitrary integer types. \CFA{} also includes a special type for !1!, !one_t!; like !zero_t!, !one_t! has built-in implicit conversions to the various integral types so that !1! maintains its expected semantics in legacy code. The addition of !one_t! allows generic algorithms to handle the unit value uniformly for types where it is meaningful; a simple example of this is that polymorphic functions\footnote{discussed in Section~\ref{poly-func-sec}} in the \CFA{} prelude define !++x! and !x++! in terms of !x += 1!, allowing users to idiomatically define all forms of increment for a type !T! by defining the single function !T& ?+=?(T&, one_t)!; analogous overloads for the decrement operators are also present, and programmers can override any of these functions for a particular type if desired. \CFA{} previously allowed !0! and !1! to be the names of polymorphic variables, with separate overloads for !int 0!, !int 1!, and !forall(dtype T) T* 0!. As revealed in my own work on generic types (Chapter~\ref{generic-chap}), the parameteric polymorphic zero variable was not generalizable to other types; though all null pointers have the same in-memory representation, the same cannot be said of the zero values of arbitrary types. As such, variables that could represent !0! and !1! were phased out in favour of functions that could generate those values for a given type as appropriate. \subsection{Polymorphic Functions} \label{poly-func-sec} The most significant feature \CFA{} adds is parametric-polymorphic functions. \end{cfa} \subsubsection{0 and 1 Literals} % TODO mention own motivating contribution % TODO mention future work in user-defined implicit conversions \subsubsection{Tuple Types} % TODO "precludes some matching strategies" \CFA{} adds \emph{tuple types} to C, a syntactic facility for referring to lists of values anonymously or with a single identifier. An identifier may name a tuple, a function may return one, and a tuple may be implicitly \emph{destructured} into its component values. The implementation of tuples in \CFACC{}'s code generation is based on the generic types introduced in Chapter~\ref{generic-chap}, with one compiler-generated generic type for each tuple arity. This allows tuples to take advantage of the same runtime optimizations available to generic types, while reducing code bloat. An extended presentation of the tuple features of \CFA{} can be found in \cite{Moss18}, but the following example shows the basics: \begin{cfa} [char, char] x = ['!', '?']; $\C{// (1); tuple type and expression syntax}$ int x = 2; $\C{// (2)}$ forall(otype T) [T, T] swap( T a, T b ) { $\C{// (3)}$ return [b, a]; $\C{// one-line swap syntax}$ } x = swap( x ); $\C{// destructure [char, char] x into two elements}$ $\C{// cannot use int x, not enough arguments}$ void swap( int, char, char ); $\C{// (4)}$ swap( x, x ); $\C{// (4) on (2), (1)}$ $\C{// not (3) on (2), (2) due to polymorphism cost}$ \end{cfa} Tuple destructuring breaks the one-to-one relationship between identifiers and values. This precludes some argument-parameter matching strategies for expression resolution, as well as cheap interpretation filters based on comparing number of parameters and arguments. As an example, in the call to !swap( x, x )! above, the second !x! can be resolved starting at the second or third parameter of !swap!, depending which interpretation of !x! was chosen for the first argument.