source: doc/theses/colby_parsons_MMAth/text/CFA_intro.tex @ ba068c0

Last change on this file since ba068c0 was aae9c17, checked in by caparsons <caparson@…>, 14 months ago

edited thesis to incorporate Gregors comments

  • Property mode set to 100644
File size: 9.5 KB
Line 
1% ======================================================================
2% ======================================================================
3\chapter{Introduction to \CFA}\label{s:cfa}
4% ======================================================================
5% ======================================================================
6
7\section{Overview}
8The following serves as an introduction to \CFA.
9\CFA is a layer over C, is transpiled\footnote{Source to source translator.} to C, and is largely considered to be an extension of C.
10Beyond C, it adds productivity features, extended libraries, an advanced type-system, and many control-flow/concurrency constructions.
11However, \CFA stays true to the C programming style, with most code revolving around @struct@'s and routines, and respects the same rules as C.
12\CFA is not object oriented as it has no notion of @this@ (receiver) and no structures with methods, but supports some object oriented ideas including constructors, destructors, and limited nominal inheritance.
13While \CFA is rich with interesting features, only the subset pertinent to this work is discussed here.
14
15\section{References}
16References in \CFA are similar to references in \CC; however \CFA references are \emph{rebindable}, and support multi-level referencing.
17References in \CFA are a layer of syntactic sugar over pointers to reduce the number of syntactic ref/deref operations needed with pointer usage.
18Pointers in \CFA differ from C and \CC in their use of @0p@ instead of C's @NULL@ or \CC's @nullptr@.
19Examples of references are shown in \VRef[Listing]{l:cfa_ref}.
20
21\begin{cfa}[caption={Example of \CFA references},label={l:cfa_ref}]
22int i = 2;
23int & ref_i = i;                        $\C{// declare ref to i}$
24int * ptr_i = &i;                       $\C{// ptr to i}$
25
26// address of ref_i is the same as address of i
27assert( &ref_i == ptr_i );
28
29int && ref_ref_i = ref_i;       $\C{// can have a ref to a ref}$
30ref_i = 3;                                      $\C{// set i to 3}$
31int new_i = 4;
32
33// syntax to rebind ref_i (must cancel implicit deref)
34&ref_i = &new_i;                        $\C{// (\&*)ref\_i = \&new\_i; (sets underlying ptr)}$
35\end{cfa}
36
37
38\section{Overloading}\label{s:Overloading}
39\CFA routines can be overloaded on parameter type, number of parameters, and \emph{return type}.
40Variables can also be overloaded on type, meaning that two variables can have the same name so long as they have different types.
41A routine or variable is disambiguated at each usage site via its type and surrounding expression context.
42A cast is used to disambiguate any conflicting usage.
43Examples of overloading are shown in \VRef[Listing]{l:cfa_overload}.
44
45\begin{cfa}[caption={Example of \CFA overloading},label={l:cfa_overload}]
46int foo() { sout | "A";  return 0;}
47int foo( int bar ) { sout | "B"; return 1; }
48int foo( double bar ) { sout | "C"; return 2; }
49double foo( double bar ) { sout | "D"; return 3; }
50void foo( double bar ) { sout | bar; }
51
52int main() {
53        foo();                                          $\C{// prints A}$
54        foo( 0 );                                       $\C{// prints B}$
55        int foo = foo( 0.0 );           $\C{// prints C}$
56        double foo = foo( 0.0 );        $\C{// prints D}$
57        foo( foo );                                     $\C{// prints 3., where left-hand side of expression is void}$
58}
59\end{cfa}
60
61
62\section{\lstinline{with} Statement}\label{s:with}
63The \CFA @with@ statement is for exposing fields of an aggregate type within a scope, allowing field names without qualification.
64This feature is also implemented in Pascal~\cite{Pascal}.
65It can exist as a stand-alone statement or wrap a routine body to expose aggregate fields.
66Examples of the @with@ statement are shown in \VRef[Listing]{l:cfa_with}.
67
68\begin{cfa}[caption={Example of \CFA \lstinline{with} statement},label={l:cfa_with}]
69struct pair {  double x, y;  };
70struct triple {  int a, b, c;  };
71pair p;
72
73@with( p )@ {                                   $\C{// stand-alone with}$
74        p.x = 6.28;  p.y = 1.73;        $\C{// long form}$
75           x = 6.28;     y = 1.73;      $\C{// short form}$
76}
77void foo( triple t, pair p ) @with( t, p )@ {  $\C{// routine with}$
78        t.a = 1;  t.b = 2;  t.c = 3;  p.x = 3.14;  p.y = 2.71;  $\C{// long form}$
79          a = 1;    b = 2;    c = 3;     x = 3.14;     y = 2.71;  $\C{// short form}$
80}
81\end{cfa}
82
83
84\section{Operators}\label{s:Operators}
85Operators can be overloaded in \CFA with operator routines.
86Operators in \CFA are named using an operator symbol and '@?@' to represent operands.
87Examples of \CFA operators are shown in \VRef[Listing]{l:cfa_operate}.
88
89\begin{cfa}[caption={Example of \CFA operators},label={l:cfa_operate}]
90struct coord {
91        double x, y, z;
92};
93coord ++@?@( coord & c ) with( c ) { $\C{// post increment}$
94        x++;  y++;  z++;
95        return c;
96}
97coord @?@<=@?@( coord op1, coord op2 ) with( op1 ) { $\C{// ambiguous with both parameters}$
98        return (x * x + y * y + z * z) <= (op2.x * op2.x + op2.y * op2.y + op2.z * op2.z);
99}
100\end{cfa}
101
102The operator '@|@' is used for \CFA stream I/O, similar to how \CC, uses operators '@<<@' and '@>>@' \VRef[Listing]{l:cfa_stream}.
103
104\begin{cfa}[caption={Example of \CFA stream I/O},label={l:cfa_stream}]
105char c;  int i;  double d;
106sin  | c | i | d; $\C{ // read into c, i, and d }$
107sout | c | i | d; $\C{ // output c, i, and d }$
108x 27 2.3                  $\C{ // implicit separation between values and auto newline }$
109\end{cfa}
110
111
112\section{Constructors and Destructors}
113Constructors and destructors in \CFA are special operator routines used for creation and destruction of objects.
114The default constructor and destructor for a type are called implicitly upon creation and deletion, respectively.
115Examples of \CFA constructors and destructors are shown in \VRef[Listing]{l:cfa_ctor}.
116
117\begin{cfa}[caption={Example of \CFA constructors and destructors},label={l:cfa_ctor}]
118struct discrete_point {
119        int x, y;
120};
121void ?{}( discrete_point & this ) with(this) { $\C{// default constructor}$
122        [x, y] = 0;
123}
124void ?{}( discrete_point & this, int x, int y ) { $\C{// explicit constructor}$
125        this.[x, y] = [x, y];
126}
127void ^?{}( discrete_point & this ) with(this) { $\C{// destructor}$
128        ?{}( this );  $\C{// reset by calling default constructor}$
129}
130int main() {
131        discrete_point x, y{}$\C{// implicit call to default ctor, ?\{\}}$
132        discrete_point s = { 2, -4 }, t{ 4, 2 }$\C{// explicit call to specialized ctor}$
133} // ^t{}, ^s{}, ^y{}, ^x{} implicit calls in reverse allocation order
134\end{cfa}
135
136
137\section{Polymorphism}\label{s:poly}
138C supports limited polymorphism, often requiring users to implement polymorphism using a @void *@ (explicit type erasure) approach.
139\CFA extends C with generalized overloading polymorphism (see \VRef{s:Overloading}), as well as parametric polymorphism and limited inclusion polymorphism (nominal inheritance).
140
141\subsection{Parametric Polymorphism}
142\CFA provides parametric polymorphism in the form of @forall@, and @trait@s.
143A @forall@ takes in a set of types and a list of constraints.
144The declarations that follow the @forall@ are parameterized over the types listed that satisfy the constraints.
145A list of @forall@ constraints can be refactored into a named @trait@ and reused in @forall@s.
146Examples of \CFA parametric polymorphism are shown in \VRef[Listing]{l:cfa_poly}.
147
148\begin{cfa}[caption={Example of \CFA parametric polymorphism},label={l:cfa_poly}]
149// sized() is a trait that means the type has a size
150forall( V & | sized(V) )                $\C{// type params for trait}$
151trait vector_space {
152        // dtor and copy ctor needed in constraints to pass by copy
153        void ?{}( V &, V & );           $\C{// copy ctor for return}$
154        void ^?{}( V & );                       $\C{// dtor}$
155        V ?+?( V, V );                          $\C{// vector addition}$
156        V ?*?( int, V );                        $\C{// scalar multiplication}$
157};
158
159forall( V & | vector_space( V ) ) {
160        V get_inverse( V v1 ) {
161                return -1 * v1;                 $\C{// can use ?*? routine defined in trait}$
162        }
163        V add_and_invert( V v1, V v2 ) {
164                return get_inverse( v1 + v2 );  $\C{// can use ?+? routine defined in trait}$
165        }
166}
167struct Vec1 { int x; };
168void ?{}( Vec1 & this, Vec1 & other ) { this.x = other.x; }
169void ?{}( Vec1 & this, int x ) { this.x = x; }
170void ^?{}( Vec1 & this ) {}
171Vec1 ?+?( Vec1 v1, Vec1 v2 ) { v1.x += v2.x; return v1; }
172Vec1 ?*?( int c, Vec1 v1 ) { v1.x = v1.x * c; return v1; }
173
174struct Vec2 { int x; int y; };
175void ?{}( Vec2 & this, Vec2 & other ) { this.x = other.x; this.y = other.y; }
176void ?{}( Vec2 & this, int x ) { this.x = x; this.y = x; }
177void ^?{}( Vec2 & this ) {}
178Vec2 ?+?( Vec2 v1, Vec2 v2 ) { v1.x += v2.x; v1.y += v2.y; return v1; }
179Vec2 ?*?( int c, Vec2 v1 ) { v1.x = v1.x * c; v1.y = v1.y * c; return v1; }
180
181int main() {
182        Vec1 v1{ 1 };                           $\C{// create Vec1 and call ctor}$
183        Vec2 v2{ 2 };                           $\C{// create Vec2 and call ctor}$
184        // can use forall defined routines since types satisfy trait
185        add_and_invert( get_inverse( v1 ), v1 );
186        add_and_invert( get_inverse( v2 ), v2 );
187}
188\end{cfa}
189
190\subsection{Inheritance}\label{s:Inheritance}
191Inheritance in \CFA is taken from Plan-9 C's nominal inheritance.
192In \CFA, @struct@s can @inline@ another struct type to gain its fields and masquerade as that type.
193Examples of \CFA nominal inheritance are shown in \VRef[Listing]{l:cfa_inherit}.
194
195\begin{cfa}[caption={Example of \CFA nominal inheritance},label={l:cfa_inherit}]
196struct one_d { double x; };
197struct two_d {
198        @inline@ one_d;
199        double y;
200};
201struct three_d {
202        @inline@ two_d;
203        double z;
204};
205double get_x( one_d & d ){ return d.x; }
206
207struct dog {};
208struct dog_food {
209        int count;
210};
211struct pet {
212        @inline@ dog;
213        @inline@ dog_food;
214};
215void pet_dog( dog & d ) { sout | "woof"; }
216void print_food( dog_food & f ) { sout | f.count; }
217
218int main() {
219        one_d x;
220        two_d y;
221        three_d z;
222        x.x = 1;
223        y.x = 2;
224        z.x = 3;
225        get_x( x );                                     $\C{// returns 1;}$
226        get_x( y );                                     $\C{// returns 2;}$
227        get_x( z );                                     $\C{// returns 3;}$
228        pet p;
229        p.count = 5;
230        pet_dog( p );                           $\C{// prints woof}$
231        print_food( p );                        $\C{// prints 5}$
232}
233\end{cfa}
234
235% Local Variables: %
236% tab-width: 4 %
237% End: %
Note: See TracBrowser for help on using the repository browser.