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

Last change on this file since ff56dd2e was 68db00e, checked in by Peter A. Buhr <pabuhr@…>, 16 months 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.