source: doc/theses/colby_parsons_MMAth/text/CFA_intro.tex @ 0faacb8

ADTast-experimental
Last change on this file since 0faacb8 was 0faacb8, checked in by caparsons <caparson@…>, 13 months ago

various additions to thesis, finished first draft of actor chapter (lots of polish needed), added first draft of intro to CFA features & intro to CFA threading, added start of mutex stmt chapter

  • Property mode set to 100644
File size: 8.9 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. \CFA is a layer over C, is transpiled to C and is largely considered to be an extension of C. Beyond C, it adds productivity features, libraries, a type system, and many other language constructions. However, \CFA stays true to C as a language, with most code revolving around \code{struct}'s and routines, and respects the same rules as C. \CFA is not object oriented as it has no notion of \code{this} and no classes or methods, but supports some object oriented adjacent ideas including costructors, destructors, and limited inheritance. \CFA is rich with interesting features, but a subset that is pertinent to this work will be discussed.
9
10\section{References}
11References in \CFA are similar to references in \CC, however in \CFA references are rebindable, and support multi-level referencing. References in \CFA are a layer of syntactic sugar over pointers to reduce the number of ref/deref operations needed with pointer usage. Some examples of references in \CFA are shown in Listing~\ref{l:cfa_ref}.
12
13
14\begin{cfacode}[tabsize=3,caption={Example of \CFA references},label={l:cfa_ref}]
15int i = 2;
16int & ref_i = i;            // declare ref to i
17int * ptr_i = &i;           // ptr to i
18
19// address of ref_i is the same as address of i
20assert( &ref_i == ptr_i );
21
22int && ref_ref_i = ref_i;   // can have a ref to a ref
23ref_i = 3;                  // set i to 3
24int new_i = 4;
25
26// syntax to rebind ref_i (must cancel implicit deref)
27&ref_i = &new_i; // (&*)ref_i = &new_i; (sets underlying ptr)
28\end{cfacode}
29
30
31\section{Overloading}
32In \CFA routines can be overloaded on parameter type, number of parameters, and return type. Variables can also be overloaded on type, meaning that two variables can have the same name so long as they have different types. The variables will be disambiguated via type, sometimes requiring a cast. The code snippet in Listing~\ref{l:cfa_overload} contains examples of overloading.
33
34
35\begin{cfacode}[tabsize=3,caption={Example of \CFA function overloading},label={l:cfa_overload}]
36int foo() { printf("A\n");  return 0;}
37int foo( int bar ) { printf("B\n"); return 1; }
38int foo( double bar ) { printf("C\n"); return 2; }
39double foo( double bar ) { printf("D\n"); return 3;}
40void foo( double bar ) { printf("%.0f\n", bar); }
41
42int main() {
43    foo();                  // prints A
44    foo( 0 );               // prints B
45    int a = foo( 0.0 );     // prints C
46    double a = foo( 0.0 );  // prints D
47    foo( a );               // prints 3
48}
49\end{cfacode}
50
51
52\section{With Statement}
53The with statement is a tool for exposing members of aggregate types within a scope in \CFA. It allows users to use fields of aggregate types without using their fully qualified name. This feature is also implemented in Pascal. It can exist as a stand-alone statement or it can be used on routines to expose fields in the body of the routine. An example is shown in Listing~\ref{l:cfa_with}.
54
55
56\begin{cfacode}[tabsize=3,caption={Usage of \CFA with statement},label={l:cfa_with}]
57struct obj {
58    int a, b, c;
59};
60struct pair {
61    double x, y;
62};
63
64// Stand-alone with stmt:
65pair p;
66with( p ) {
67    x = 6.28;
68    y = 1.73;
69}
70
71// Can be used on routines:
72void foo( obj o, pair p ) with( o, p ) {
73    a = 1;
74    b = 2;
75    c = 3;
76    x = 3.14;
77    y = 2.71;
78}
79
80// routine foo is equivalent to routine bar:
81void bar( obj o, pair p ) {
82    o.a = 1;
83    o.b = 2;
84    o.c = 3;
85    p.x = 3.14;
86    p.y = 2.71;
87}
88\end{cfacode}
89
90
91\section{Operators}
92Operators can be overloaded in \CFA with operator routines. Operators in \CFA are named using the operator symbol and '?' to respresent operands.
93An example is shown in Listing~\ref{l:cfa_operate}.
94
95
96\begin{cfacode}[tabsize=3,caption={Example of \CFA operators},label={l:cfa_operate}]
97struct coord {
98    double x;
99    double y;
100    double z;
101};
102coord ++?( coord & c ) with(c) {
103    x++;
104    y++;
105    z++;
106    return c;
107}
108coord ?<=?( coord op1, coord op2 ) with( op1 ) {
109    return (x*x + y*y + z*z) <=
110        (op2.x*op2.x + op2.y*op2.y + op2.z*op2.z);
111}
112\end{cfacode}
113
114
115\section{Constructors and Destructors}
116Constructors and destructors in \CFA are two special operator routines that are used for creation and destruction of objects. The default constructor and destructor for a type are called implicitly upon creation and deletion respectively if they are defined. An example is shown in Listing~\ref{l:cfa_ctor}.
117
118
119\begin{cfacode}[tabsize=3,caption={Example of \CFA constructors and destructors},label={l:cfa_ctor}]
120struct discrete_point {
121    int x;
122    int y;
123};
124void ?{}( discrete_point & this ) with(this) { // ctor
125    x = 0;
126    y = 0;
127}
128void ?{}( discrete_point & this, int x, int y ) { // ctor
129    this.x = x;
130    this.y = y;
131}
132void ^?{}( discrete_point & this ) with(this) { // dtor
133    x = 0;
134    y = 0;
135}
136
137int main() {
138    discrete_point d; // implicit call to ?{}
139    discrete_point p{}; // same call as line above
140    discrete_point dp{ 2, -4 }; // specialized ctor
141} // ^d{}, ^p{}, ^dp{} all called as they go out of scope
142\end{cfacode}
143
144
145\section{Polymorphism}\label{s:poly}
146C does not natively support polymorphism, and requires users to implement polymorphism themselves if they want to use it. \CFA extends C with two styles of polymorphism that it supports, parametric polymorphism and nominal inheritance.
147
148\subsection{Parametric Polymorphism}
149\CFA provides parametric polymorphism in the form of \code{forall}, and \code{trait}s. A \code{forall} takes in a set of types and a list of constraints. The declarations that follow the \code{forall} are parameterized over the types listed that satisfy the constraints. Sometimes the list of constraints can be long, which is where a \code{trait} can be used. A \code{trait} is a collection of constraints that is given a name and can be reused in foralls. An example of the usage of parametric polymorphism in \CFA is shown in Listing~\ref{l:cfa_poly}.
150
151\begin{cfacode}[tabsize=3,caption={Example of \CFA polymorphism},label={l:cfa_poly}]
152// sized() is a trait that means the type has a size
153forall( V & | sized(V) )        // type params for trait
154trait vector_space {
155    V add( V, V );              // vector addition
156    V scalar_mult( int, V );    // scalar multiplication
157
158    // dtor and copy ctor needed in constraints to pass by copy
159    void ?{}( V &, V & );       // copy ctor for return
160    void ^?{}( V & );           // dtor
161};
162
163forall( V & | vector_space( V )) {
164    V get_inverse( V v1 ) {
165        return scalar_mult( -1, v1 );  // can use ?*? routine defined in trait
166    }
167    V add_and_invert( V v1, V v2 ) {
168        return get_inverse( add( v1, v2 ) );  // can use ?*? routine defined in trait
169    }
170}
171struct Vec1 { int x; };
172void ?{}( Vec1 & this, Vec1 & other ) { this.x = other.x; }
173void ?{}( Vec1 & this, int x ) { this.x = x; }
174void ^?{}( Vec1 & this ) {}
175Vec1 add( Vec1 v1, Vec1 v2 ) { v1.x += v2.x; return v1; }
176Vec1 scalar_mult( int c, Vec1 v1 ) { v1.x = v1.x * c; return v1; }
177
178struct Vec2 { int x; int y; };
179void ?{}( Vec2 & this, Vec2 & other ) { this.x = other.x; this.y = other.y; }
180void ?{}( Vec2 & this, int x ) { this.x = x; this.y = x; }
181void ^?{}( Vec2 & this ) {}
182Vec2 add( Vec2 v1, Vec2 v2 ) { v1.x += v2.x; v1.y += v2.y; return v1; }
183Vec2 scalar_mult( int c, Vec2 v1 ) { v1.x = v1.x * c; v1.y = v1.y * c; return v1; }
184
185int main() {
186    Vec1 v1{ 1 }; // create Vec1 and call ctor
187    Vec2 v2{ 2 }; // create Vec2 and call ctor
188
189    // can use forall defined routines since types satisfy trait
190    add_and_invert( get_inverse( v1 ), v1 );
191    add_and_invert( get_inverse( v2 ), v2 );
192}
193
194\end{cfacode}
195
196\subsection{Inheritance}
197Inheritance in \CFA copies its style from Plan-9 C nominal inheritance. In \CFA structs can \code{inline} another struct type to gain its fields and to be able to be passed to routines that require a parameter of the inlined type. An example of \CFA inheritance is shown in Listing~\ref{l:cfa_inherit}.
198
199\begin{cfacode}[tabsize=3,caption={Example of \CFA inheritance},label={l:cfa_inherit}]
200struct one_d { double x; };
201struct two_d { 
202    inline one_d;
203    double y;
204};
205struct three_d { 
206    inline two_d;
207    double z;
208};
209double get_x( one_d & d ){ return d.x; }
210
211struct dog {};
212struct dog_food {
213    int count;
214};
215struct pet {
216    inline dog;
217    inline dog_food;
218};
219void pet_dog( dog & d ){printf("woof\n");}
220void print_food( dog_food & f ){printf("%d\n", f.count);}
221
222int main() {
223    one_d x;
224    two_d y;
225    three_d z;
226    x.x = 1;
227    y.x = 2;
228    z.x = 3;
229    get_x( x ); // returns 1;
230    get_x( y ); // returns 2;
231    get_x( z ); // returns 3;
232    pet p;
233    p.count = 5;
234    pet_dog( p );    // prints woof
235    print_food( p ); // prints 5
236}
237\end{cfacode}
238
239
Note: See TracBrowser for help on using the repository browser.