[601bd9e] | 1 | % ====================================================================== |
---|
| 2 | % ====================================================================== |
---|
| 3 | \chapter{Introduction to \CFA}\label{s:cfa} |
---|
| 4 | % ====================================================================== |
---|
| 5 | % ====================================================================== |
---|
| 6 | |
---|
| 7 | \section{Overview} |
---|
[c459f99] | 8 | The 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. |
---|
| 10 | Beyond C, it adds productivity features, extended libraries, an advanced type-system, and many control-flow/concurrency constructions. |
---|
[9509d67a] | 11 | However, \CFA stays true to the C programming style, with most code revolving around @struct@s and routines, and respects the same rules as C. |
---|
[2d831a1] | 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. |
---|
[aae9c17] | 13 | While \CFA is rich with interesting features, only the subset pertinent to this work is discussed here. |
---|
[0faacb8] | 14 | |
---|
| 15 | \section{References} |
---|
[c459f99] | 16 | References in \CFA are similar to references in \CC; however \CFA references are \emph{rebindable}, and support multi-level referencing. |
---|
[aae9c17] | 17 | References in \CFA are a layer of syntactic sugar over pointers to reduce the number of syntactic ref/deref operations needed with pointer usage. |
---|
| 18 | Pointers in \CFA differ from C and \CC in their use of @0p@ instead of C's @NULL@ or \CC's @nullptr@. |
---|
[9509d67a] | 19 | References can contain 0p in \CFA, which is the equivalent of a null reference. |
---|
[c459f99] | 20 | Examples of references are shown in \VRef[Listing]{l:cfa_ref}. |
---|
[0faacb8] | 21 | |
---|
[0e398ad] | 22 | \begin{cfa}[caption={Example of \CFA references},label={l:cfa_ref}] |
---|
[0faacb8] | 23 | int i = 2; |
---|
[59c05958] | 24 | int & ref_i = i; $\C{// declare ref to i}$ |
---|
| 25 | int * ptr_i = &i; $\C{// ptr to i}$ |
---|
[0faacb8] | 26 | |
---|
| 27 | // address of ref_i is the same as address of i |
---|
| 28 | assert( &ref_i == ptr_i ); |
---|
| 29 | |
---|
[59c05958] | 30 | int && ref_ref_i = ref_i; $\C{// can have a ref to a ref}$ |
---|
| 31 | ref_i = 3; $\C{// set i to 3}$ |
---|
[0faacb8] | 32 | int new_i = 4; |
---|
| 33 | |
---|
| 34 | // syntax to rebind ref_i (must cancel implicit deref) |
---|
[59c05958] | 35 | &ref_i = &new_i; $\C{// (\&*)ref\_i = \&new\_i; (sets underlying ptr)}$ |
---|
[0e398ad] | 36 | \end{cfa} |
---|
[601bd9e] | 37 | |
---|
| 38 | |
---|
[59c05958] | 39 | \section{Overloading}\label{s:Overloading} |
---|
[c459f99] | 40 | \CFA routines can be overloaded on parameter type, number of parameters, and \emph{return type}. |
---|
| 41 | Variables can also be overloaded on type, meaning that two variables can have the same name so long as they have different types. |
---|
[59c05958] | 42 | A routine or variable is disambiguated at each usage site via its type and surrounding expression context. |
---|
[c459f99] | 43 | A cast is used to disambiguate any conflicting usage. |
---|
| 44 | Examples of overloading are shown in \VRef[Listing]{l:cfa_overload}. |
---|
[0faacb8] | 45 | |
---|
[59c05958] | 46 | \begin{cfa}[caption={Example of \CFA overloading},label={l:cfa_overload}] |
---|
| 47 | int foo() { sout | "A"; return 0;} |
---|
| 48 | int foo( int bar ) { sout | "B"; return 1; } |
---|
| 49 | int foo( double bar ) { sout | "C"; return 2; } |
---|
| 50 | double foo( double bar ) { sout | "D"; return 3; } |
---|
| 51 | void foo( double bar ) { sout | bar; } |
---|
[0faacb8] | 52 | |
---|
| 53 | int main() { |
---|
[59c05958] | 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}$ |
---|
[0faacb8] | 59 | } |
---|
[0e398ad] | 60 | \end{cfa} |
---|
[601bd9e] | 61 | |
---|
| 62 | |
---|
[68db00e] | 63 | \section{\lstinline{with} Statement}\label{s:with} |
---|
[59c05958] | 64 | The \CFA @with@ statement is for exposing fields of an aggregate type within a scope, allowing field names without qualification. |
---|
[c459f99] | 65 | This feature is also implemented in Pascal~\cite{Pascal}. |
---|
| 66 | It can exist as a stand-alone statement or wrap a routine body to expose aggregate fields. |
---|
[9509d67a] | 67 | If exposed fields share a name, the type system will attempt to disambiguate them based on type. |
---|
| 68 | If the type system is unable to disambiguate the fields then the user must qualify those names to avoid a compilation error. |
---|
[c459f99] | 69 | Examples of the @with@ statement are shown in \VRef[Listing]{l:cfa_with}. |
---|
[59c05958] | 70 | |
---|
| 71 | \begin{cfa}[caption={Example of \CFA \lstinline{with} statement},label={l:cfa_with}] |
---|
| 72 | struct pair { double x, y; }; |
---|
| 73 | struct triple { int a, b, c; }; |
---|
[0faacb8] | 74 | pair p; |
---|
| 75 | |
---|
[59c05958] | 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}$ |
---|
[0faacb8] | 79 | } |
---|
[59c05958] | 80 | void 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}$ |
---|
[0faacb8] | 83 | } |
---|
[0e398ad] | 84 | \end{cfa} |
---|
[0faacb8] | 85 | |
---|
| 86 | |
---|
[68db00e] | 87 | \section{Operators}\label{s:Operators} |
---|
[c459f99] | 88 | Operators can be overloaded in \CFA with operator routines. |
---|
[59c05958] | 89 | Operators in \CFA are named using an operator symbol and '@?@' to represent operands. |
---|
[c459f99] | 90 | Examples of \CFA operators are shown in \VRef[Listing]{l:cfa_operate}. |
---|
[0faacb8] | 91 | |
---|
[59c05958] | 92 | \begin{cfa}[caption={Example of \CFA operators},label={l:cfa_operate}] |
---|
[0faacb8] | 93 | struct coord { |
---|
[59c05958] | 94 | double x, y, z; |
---|
[0faacb8] | 95 | }; |
---|
[59c05958] | 96 | coord ++@?@( coord & c ) with( c ) { $\C{// post increment}$ |
---|
| 97 | x++; y++; z++; |
---|
| 98 | return c; |
---|
[0faacb8] | 99 | } |
---|
[59c05958] | 100 | coord @?@<=@?@( 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); |
---|
[0faacb8] | 102 | } |
---|
[0e398ad] | 103 | \end{cfa} |
---|
[0faacb8] | 104 | |
---|
[aae9c17] | 105 | The 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}] |
---|
| 108 | char c; int i; double d; |
---|
| 109 | sin | c | i | d; $\C{ // read into c, i, and d }$ |
---|
| 110 | sout | c | i | d; $\C{ // output c, i, and d }$ |
---|
| 111 | x 27 2.3 $\C{ // implicit separation between values and auto newline }$ |
---|
| 112 | \end{cfa} |
---|
| 113 | |
---|
[0faacb8] | 114 | |
---|
| 115 | \section{Constructors and Destructors} |
---|
[c459f99] | 116 | Constructors and destructors in \CFA are special operator routines used for creation and destruction of objects. |
---|
| 117 | The default constructor and destructor for a type are called implicitly upon creation and deletion, respectively. |
---|
| 118 | Examples of \CFA constructors and destructors are shown in \VRef[Listing]{l:cfa_ctor}. |
---|
[0faacb8] | 119 | |
---|
[59c05958] | 120 | \begin{cfa}[caption={Example of \CFA constructors and destructors},label={l:cfa_ctor}] |
---|
[0faacb8] | 121 | struct discrete_point { |
---|
[59c05958] | 122 | int x, y; |
---|
[0faacb8] | 123 | }; |
---|
[59c05958] | 124 | void ?{}( discrete_point & this ) with(this) { $\C{// default constructor}$ |
---|
| 125 | [x, y] = 0; |
---|
[0faacb8] | 126 | } |
---|
[59c05958] | 127 | void ?{}( discrete_point & this, int x, int y ) { $\C{// explicit constructor}$ |
---|
| 128 | this.[x, y] = [x, y]; |
---|
[0faacb8] | 129 | } |
---|
[59c05958] | 130 | void ^?{}( discrete_point & this ) with(this) { $\C{// destructor}$ |
---|
| 131 | ?{}( this ); $\C{// reset by calling default constructor}$ |
---|
[0faacb8] | 132 | } |
---|
| 133 | int main() { |
---|
[59c05958] | 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 |
---|
[0e398ad] | 137 | \end{cfa} |
---|
[0faacb8] | 138 | |
---|
| 139 | |
---|
| 140 | \section{Polymorphism}\label{s:poly} |
---|
[aae9c17] | 141 | C 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). |
---|
[0faacb8] | 143 | |
---|
| 144 | \subsection{Parametric Polymorphism} |
---|
[c459f99] | 145 | \CFA provides parametric polymorphism in the form of @forall@, and @trait@s. |
---|
| 146 | A @forall@ takes in a set of types and a list of constraints. |
---|
| 147 | The declarations that follow the @forall@ are parameterized over the types listed that satisfy the constraints. |
---|
| 148 | A list of @forall@ constraints can be refactored into a named @trait@ and reused in @forall@s. |
---|
| 149 | Examples of \CFA parametric polymorphism are shown in \VRef[Listing]{l:cfa_poly}. |
---|
[0faacb8] | 150 | |
---|
[59c05958] | 151 | \begin{cfa}[caption={Example of \CFA parametric polymorphism},label={l:cfa_poly}] |
---|
[0faacb8] | 152 | // sized() is a trait that means the type has a size |
---|
[59c05958] | 153 | forall( V & | sized(V) ) $\C{// type params for trait}$ |
---|
[0faacb8] | 154 | trait vector_space { |
---|
[59c05958] | 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}$ |
---|
[0faacb8] | 160 | }; |
---|
| 161 | |
---|
[59c05958] | 162 | forall( 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 | } |
---|
[0faacb8] | 169 | } |
---|
| 170 | struct Vec1 { int x; }; |
---|
| 171 | void ?{}( Vec1 & this, Vec1 & other ) { this.x = other.x; } |
---|
| 172 | void ?{}( Vec1 & this, int x ) { this.x = x; } |
---|
| 173 | void ^?{}( Vec1 & this ) {} |
---|
[59c05958] | 174 | Vec1 ?+?( Vec1 v1, Vec1 v2 ) { v1.x += v2.x; return v1; } |
---|
| 175 | Vec1 ?*?( int c, Vec1 v1 ) { v1.x = v1.x * c; return v1; } |
---|
[0faacb8] | 176 | |
---|
| 177 | struct Vec2 { int x; int y; }; |
---|
| 178 | void ?{}( Vec2 & this, Vec2 & other ) { this.x = other.x; this.y = other.y; } |
---|
| 179 | void ?{}( Vec2 & this, int x ) { this.x = x; this.y = x; } |
---|
| 180 | void ^?{}( Vec2 & this ) {} |
---|
[59c05958] | 181 | Vec2 ?+?( Vec2 v1, Vec2 v2 ) { v1.x += v2.x; v1.y += v2.y; return v1; } |
---|
| 182 | Vec2 ?*?( int c, Vec2 v1 ) { v1.x = v1.x * c; v1.y = v1.y * c; return v1; } |
---|
[0faacb8] | 183 | |
---|
| 184 | int main() { |
---|
[59c05958] | 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 ); |
---|
[0faacb8] | 190 | } |
---|
[0e398ad] | 191 | \end{cfa} |
---|
[0faacb8] | 192 | |
---|
[4f6c628] | 193 | \subsection{Inheritance}\label{s:Inheritance} |
---|
[2d831a1] | 194 | Inheritance in \CFA is taken from Plan-9 C's nominal inheritance. |
---|
[c459f99] | 195 | In \CFA, @struct@s can @inline@ another struct type to gain its fields and masquerade as that type. |
---|
[2d831a1] | 196 | Examples of \CFA nominal inheritance are shown in \VRef[Listing]{l:cfa_inherit}. |
---|
[0faacb8] | 197 | |
---|
[2d831a1] | 198 | \begin{cfa}[caption={Example of \CFA nominal inheritance},label={l:cfa_inherit}] |
---|
[0faacb8] | 199 | struct one_d { double x; }; |
---|
[c459f99] | 200 | struct two_d { |
---|
[59c05958] | 201 | @inline@ one_d; |
---|
| 202 | double y; |
---|
[0faacb8] | 203 | }; |
---|
[c459f99] | 204 | struct three_d { |
---|
[59c05958] | 205 | @inline@ two_d; |
---|
| 206 | double z; |
---|
[0faacb8] | 207 | }; |
---|
| 208 | double get_x( one_d & d ){ return d.x; } |
---|
| 209 | |
---|
| 210 | struct dog {}; |
---|
| 211 | struct dog_food { |
---|
[59c05958] | 212 | int count; |
---|
[0faacb8] | 213 | }; |
---|
| 214 | struct pet { |
---|
[59c05958] | 215 | @inline@ dog; |
---|
| 216 | @inline@ dog_food; |
---|
[0faacb8] | 217 | }; |
---|
[59c05958] | 218 | void pet_dog( dog & d ) { sout | "woof"; } |
---|
| 219 | void print_food( dog_food & f ) { sout | f.count; } |
---|
[0faacb8] | 220 | |
---|
| 221 | int main() { |
---|
[59c05958] | 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}$ |
---|
[0faacb8] | 235 | } |
---|
[0e398ad] | 236 | \end{cfa} |
---|
[0faacb8] | 237 | |
---|
[59c05958] | 238 | % Local Variables: % |
---|
| 239 | % tab-width: 4 % |
---|
| 240 | % End: % |
---|