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

ADTast-experimental
Last change on this file since 0e398ad was 0e398ad, checked in by Peter A. Buhr <pabuhr@…>, 19 months ago

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