source: doc/theses/colby_parsons_MMAth/text/CFA_intro.tex @ 4dab7e8

Last change on this file since 4dab7e8 was 9509d67a, checked in by caparsons <caparson@…>, 14 months ago

Incorporated changes in response to Trevor's comments.

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