source: doc/theses/colby_parsons_MMAth/text/CFA_intro.tex@ 7ed01be

Last change on this file since 7ed01be was 68db00e, checked in by Peter A. Buhr <pabuhr@…>, 2 years ago

add labels to sections

  • Property mode set to 100644
File size: 9.0 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.
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 ref/deref operations needed with pointer usage.
18Another difference is the 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
102
103\section{Constructors and Destructors}
104Constructors and destructors in \CFA are special operator routines used for creation and destruction of objects.
105The default constructor and destructor for a type are called implicitly upon creation and deletion, respectively.
106Examples of \CFA constructors and destructors are shown in \VRef[Listing]{l:cfa_ctor}.
107
108\begin{cfa}[caption={Example of \CFA constructors and destructors},label={l:cfa_ctor}]
109struct discrete_point {
110 int x, y;
111};
112void ?{}( discrete_point & this ) with(this) { $\C{// default constructor}$
113 [x, y] = 0;
114}
115void ?{}( discrete_point & this, int x, int y ) { $\C{// explicit constructor}$
116 this.[x, y] = [x, y];
117}
118void ^?{}( discrete_point & this ) with(this) { $\C{// destructor}$
119 ?{}( this ); $\C{// reset by calling default constructor}$
120}
121int main() {
122 discrete_point x, y{}; $\C{// implicit call to default ctor, ?\{\}}$
123 discrete_point s = { 2, -4 }, t{ 4, 2 }; $\C{// explicit call to specialized ctor}$
124} // ^t{}, ^s{}, ^y{}, ^x{} implicit calls in reverse allocation order
125\end{cfa}
126
127
128\section{Polymorphism}\label{s:poly}
129C supports limited polymorphism, often requiring users to implement polymorphism using a @void *@ (type erasure) approach.
130\CFA extends C with generalized overloading polymorphism (see \VRef{s:Overloading}), as well as, parametric polymorphism and limited nominal inheritance.
131
132\subsection{Parametric Polymorphism}
133\CFA provides parametric polymorphism in the form of @forall@, and @trait@s.
134A @forall@ takes in a set of types and a list of constraints.
135The declarations that follow the @forall@ are parameterized over the types listed that satisfy the constraints.
136A list of @forall@ constraints can be refactored into a named @trait@ and reused in @forall@s.
137Examples of \CFA parametric polymorphism are shown in \VRef[Listing]{l:cfa_poly}.
138
139\begin{cfa}[caption={Example of \CFA parametric polymorphism},label={l:cfa_poly}]
140// sized() is a trait that means the type has a size
141forall( V & | sized(V) ) $\C{// type params for trait}$
142trait vector_space {
143 // dtor and copy ctor needed in constraints to pass by copy
144 void ?{}( V &, V & ); $\C{// copy ctor for return}$
145 void ^?{}( V & ); $\C{// dtor}$
146 V ?+?( V, V ); $\C{// vector addition}$
147 V ?*?( int, V ); $\C{// scalar multiplication}$
148};
149
150forall( V & | vector_space( V ) ) {
151 V get_inverse( V v1 ) {
152 return -1 * v1; $\C{// can use ?*? routine defined in trait}$
153 }
154 V add_and_invert( V v1, V v2 ) {
155 return get_inverse( v1 + v2 ); $\C{// can use ?+? routine defined in trait}$
156 }
157}
158struct Vec1 { int x; };
159void ?{}( Vec1 & this, Vec1 & other ) { this.x = other.x; }
160void ?{}( Vec1 & this, int x ) { this.x = x; }
161void ^?{}( Vec1 & this ) {}
162Vec1 ?+?( Vec1 v1, Vec1 v2 ) { v1.x += v2.x; return v1; }
163Vec1 ?*?( int c, Vec1 v1 ) { v1.x = v1.x * c; return v1; }
164
165struct Vec2 { int x; int y; };
166void ?{}( Vec2 & this, Vec2 & other ) { this.x = other.x; this.y = other.y; }
167void ?{}( Vec2 & this, int x ) { this.x = x; this.y = x; }
168void ^?{}( Vec2 & this ) {}
169Vec2 ?+?( Vec2 v1, Vec2 v2 ) { v1.x += v2.x; v1.y += v2.y; return v1; }
170Vec2 ?*?( int c, Vec2 v1 ) { v1.x = v1.x * c; v1.y = v1.y * c; return v1; }
171
172int main() {
173 Vec1 v1{ 1 }; $\C{// create Vec1 and call ctor}$
174 Vec2 v2{ 2 }; $\C{// create Vec2 and call ctor}$
175 // can use forall defined routines since types satisfy trait
176 add_and_invert( get_inverse( v1 ), v1 );
177 add_and_invert( get_inverse( v2 ), v2 );
178}
179\end{cfa}
180
181\subsection{Inheritance}\label{s:Inheritance}
182Inheritance in \CFA is taken from Plan-9 C's nominal inheritance.
183In \CFA, @struct@s can @inline@ another struct type to gain its fields and masquerade as that type.
184Examples of \CFA nominal inheritance are shown in \VRef[Listing]{l:cfa_inherit}.
185
186\begin{cfa}[caption={Example of \CFA nominal inheritance},label={l:cfa_inherit}]
187struct one_d { double x; };
188struct two_d {
189 @inline@ one_d;
190 double y;
191};
192struct three_d {
193 @inline@ two_d;
194 double z;
195};
196double get_x( one_d & d ){ return d.x; }
197
198struct dog {};
199struct dog_food {
200 int count;
201};
202struct pet {
203 @inline@ dog;
204 @inline@ dog_food;
205};
206void pet_dog( dog & d ) { sout | "woof"; }
207void print_food( dog_food & f ) { sout | f.count; }
208
209int main() {
210 one_d x;
211 two_d y;
212 three_d z;
213 x.x = 1;
214 y.x = 2;
215 z.x = 3;
216 get_x( x ); $\C{// returns 1;}$
217 get_x( y ); $\C{// returns 2;}$
218 get_x( z ); $\C{// returns 3;}$
219 pet p;
220 p.count = 5;
221 pet_dog( p ); $\C{// prints woof}$
222 print_food( p ); $\C{// prints 5}$
223}
224\end{cfa}
225
226% Local Variables: %
227% tab-width: 4 %
228% End: %
Note: See TracBrowser for help on using the repository browser.