Changeset 10c7f40 for doc/user/user.tex


Ignore:
Timestamp:
Feb 15, 2021, 10:41:44 AM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
e94eeb9
Parents:
52f6250
Message:

formatting, rewrite section of "with" statement

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/user/user.tex

    r52f6250 r10c7f40  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Mon Feb  8 21:53:31 2021
    14 %% Update Count     : 4327
     13%% Last Modified On : Mon Feb 15 09:54:33 2021
     14%% Update Count     : 4442
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    105105
    106106\author{
    107 \huge \CFA Team \medskip \\
     107\huge \CFA Team (past and present) \medskip \\
    108108\Large Andrew Beach, Richard Bilson, Michael Brooks, Peter A. Buhr, Thierry Delisle, \smallskip \\
    109109\Large Glen Ditchfield, Rodolfo G. Esteves, Aaron Moss, Colby Parsons, Rob Schluntz, \smallskip \\
     
    129129\vspace*{\fill}
    130130\noindent
    131 \copyright\,2016 \CFA Project \\ \\
     131\copyright\,2016, 2018, 2021 \CFA Project \\ \\
    132132\noindent
    133133This work is licensed under the Creative Commons Attribution 4.0 International License.
     
    970970\hline
    971971\begin{cfa}
    972 while @()@ { sout | "empty"; break; }
    973 do { sout | "empty"; break; } while @()@;
    974 for @()@ { sout | "empty"; break; }
     972while @($\,$)@ { sout | "empty"; break; }
     973do { sout | "empty"; break; } while @($\,$)@;
     974for @($\,$)@ { sout | "empty"; break; }
    975975for ( @0@ ) { sout | "A"; } sout | "zero";
    976976for ( @1@ ) { sout | "A"; }
     
    11451145\subsection{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break} Statement}{Labelled continue / break Statement}}
    11461146
    1147 While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure.
    1148 Unfortunately, this restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting.
     1147C ©continue© and ©break© statements, for altering control flow, are restricted to one level of nesting for a particular control structure.
     1148This restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting.
    11491149To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@©continue©!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@©break©!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85}, as in Java.
    11501150For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement;
    11511151for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement.
    1152 \VRef[Figure]{f:MultiLevelExit} shows ©continue© and ©break© indicating the specific control structure, and the corresponding C program using only ©goto© and labels.
     1152\VRef[Figure]{f:MultiLevelExit} shows a comparison between labelled ©continue© and ©break© and the corresponding C equivalent using ©goto© and labels.
    11531153The innermost loop has 8 exit points, which cause continuation or termination of one or more of the 7 \Index{nested control-structure}s.
    11541154
     
    12151215\end{lrbox}
    12161216
    1217 \hspace*{-10pt}
    12181217\subfloat[\CFA]{\label{f:CFibonacci}\usebox\myboxA}
    1219 \hspace{2pt}
     1218\hspace{3pt}
    12201219\vrule
     1220\hspace{3pt}
    12211221\subfloat[C]{\label{f:CFAFibonacciGen}\usebox\myboxB}
    12221222\caption{Multi-level Exit}
     
    12331233This restriction prevents missing declarations and/or initializations at the start of a control structure resulting in undefined behaviour.
    12341234\end{itemize}
    1235 The advantage of the labelled ©continue©/©break© is allowing static multi-level exits without having to use the ©goto© statement, and tying control flow to the target control structure rather than an arbitrary point in a program.
     1235The advantage of the labelled ©continue©/©break© is allowing static multi-level exits without having to use the ©goto© statement, and tying control flow to the target control structure rather than an arbitrary point in a program via a label.
    12361236Furthermore, the location of the label at the \emph{beginning} of the target control structure informs the reader (\Index{eye candy}) that complex control-flow is occurring in the body of the control structure.
    12371237With ©goto©, the label is at the end of the control structure, which fails to convey this important clue early enough to the reader.
     
    12401240
    12411241
    1242 %\section{\texorpdfstring{\protect\lstinline@with@ Statement}{with Statement}}
    1243 \section{\texorpdfstring{\LstKeywordStyle{with} Statement}{with Statement}}
     1242%\subsection{\texorpdfstring{\protect\lstinline@with@ Statement}{with Statement}}
     1243\subsection{\texorpdfstring{\LstKeywordStyle{with} Statement}{with Statement}}
    12441244\label{s:WithStatement}
    12451245
    1246 Grouping heterogeneous data into \newterm{aggregate}s (structure/union) is a common programming practice, and an aggregate can be further organized into more complex structures, such as arrays and containers:
    1247 \begin{cfa}
    1248 struct S { $\C{// aggregate}$
    1249         char c; $\C{// fields}$
    1250         int i;
    1251         double d;
     1246Grouping heterogeneous data into an \newterm{aggregate} (structure/union) is a common programming practice, and aggregates may be nested:
     1247\begin{cfa}
     1248struct Person {                                                         $\C{// aggregate}$
     1249        struct Name {                                                   $\C{// nesting}$
     1250                char first[20], last[20];
     1251        } name;
     1252        struct Address {                                                $\C{// nesting}$
     1253                ...
     1254        } address;
     1255        int sex;
    12521256};
    1253 S s, as[10];
    1254 \end{cfa}
    1255 However, functions manipulating aggregates must repeat the aggregate name to access its containing fields:
    1256 \begin{cfa}
    1257 void f( S s ) {
    1258         @s.@c; @s.@i; @s.@d; $\C{// access containing fields}$
    1259 }
    1260 \end{cfa}
    1261 which extends to multiple levels of qualification for nested aggregates.
    1262 A similar situation occurs in object-oriented programming, \eg \CC:
     1257\end{cfa}
     1258Functions manipulating aggregates must repeat the aggregate name to access its containing fields.
     1259\begin{cfa}
     1260Person p
     1261@p.@name; @p.@address; @p.@sex; $\C{// access containing fields}$
     1262\end{cfa}
     1263which extends to multiple levels of qualification for nested aggregates and multiple aggregates.
     1264\begin{cfa}
     1265struct Ticket { ... } t;
     1266@p.name@.first; @p.address@.street;             $\C{// access nested fields}$
     1267@t.@departure; @t.@cost;                                $\C{// access multiple aggregate}$
     1268\end{cfa}
     1269Repeated aggregate qualification is tedious and makes code difficult to read.
     1270Therefore, reducing aggregate qualification is a useful language design goal.
     1271
     1272C allows unnamed nested aggregates that open their scope into the containing aggregate.
     1273However, this feature is only useful for ©union© aggregates.
     1274\begin{cfa}
     1275struct S {
     1276        union {
     1277                char @c@;   int @i@;   double @d@;
     1278        };
     1279        int tag;
     1280} s;
     1281@s@.tag; @s@.c; @s@.i; @s@.d;                           $\C{// no nested qualification for union fields}$
     1282\end{cfa}
     1283
     1284Object-oriented languages reduce qualification for class variables within member functions, \eg \CC:
    12631285\begin{C++}
    12641286struct S {
    1265         char c; $\C{// fields}$
    1266         int i;
    1267         double d;
    1268         void f() { $\C{// implicit ``this'' aggregate}$
    1269                 @this->@c; @this->@i; @this->@d; $\C{// access containing fields}$
     1287        char @c@;   int @i@;   double @d@;
     1288        void f( /* S * this */ ) {                              $\C{// implicit ``this'' parameter}$
     1289                @c@;   @i@;   @d@;                                      $\C{// this->c; this->i; this->d;}$
    12701290        }
    12711291}
    12721292\end{C++}
    1273 Object-oriented nesting of member functions in a \lstinline[language=C++]@class/struct@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
    1274 However, for other aggregate parameters, qualification is necessary:
    1275 \begin{cfa}
    1276 struct T { double m, n; };
    1277 int S::f( T & t ) { $\C{// multiple aggregate parameters}$
    1278         c; i; d; $\C{\R{// this--{\textgreater}c, this--{\textgreater}i, this--{\textgreater}d}}$
    1279         @t.@m; @t.@n; $\C{// must qualify}$
    1280 }
    1281 \end{cfa}
    1282 
    1283 To simplify the programmer experience, \CFA provides a ©with© statement \see{Pascal~\cite[\S~4.F]{Pascal}} to elide aggregate qualification to fields by opening a scope containing the field identifiers.
    1284 Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block.
    1285 \begin{cfa}
    1286 void f( S & this ) @with ( this )@ { $\C{// with statement}$
    1287         c; i; d; $\C{\R{// this.c, this.i, this.d}}$
     1293In general, qualification is elided for the variables and functions in the lexical scopes visible from a member function.
     1294However, qualification is necessary for name shadowing and explicit aggregate parameters.
     1295\begin{cfa}
     1296struct T {
     1297        char @m@;   int @i@;   double @n@;              $\C{// derived class variables}$
     1298};
     1299struct S : public T {
     1300        char @c@;   int @i@;   double @d@;              $\C{// class variables}$
     1301        void g( double @d@, T & t ) {
     1302                d;   @t@.m;   @t@.i;   @t@.n;           $\C{// function parameter}$
     1303                c;   i;   @this->@d;   @S::@d;          $\C{// class S variables}$
     1304                m;   @T::@i;   n;                                       $\C{// class T variables}$
     1305        }
     1306};
     1307\end{cfa}
     1308Note the three different forms of qualification syntax in \CC, ©.©, ©->©, ©::©, which is confusing.
     1309
     1310Since \CFA in not object-oriented, it has no implicit parameter with its implicit qualification.
     1311Instead \CFA introduces a general mechanism using the ©with© statement \see{Pascal~\cite[\S~4.F]{Pascal}} to explicitly elide aggregate qualification by opening a scope containing the field identifiers.
     1312Hence, the qualified fields become variables with the side-effect that it is simpler to write, easier to read, and optimize field references in a block.
     1313\begin{cfa}
     1314void f( S & this ) @with ( this )@ {            $\C{// with statement}$
     1315        @c@;   @i@;   @d@;                                              $\C{// this.c, this.i, this.d}$
    12881316}
    12891317\end{cfa}
    12901318with the generality of opening multiple aggregate-parameters:
    12911319\begin{cfa}
    1292 void f( S & s, T & t ) @with ( s, t )@ { $\C{// multiple aggregate parameters}$
    1293         c; i; d; $\C{\R{// s.c, s.i, s.d}}$
    1294         m; n; $\C{\R{// t.m, t.n}}$
    1295 }
    1296 \end{cfa}
    1297 
    1298 In detail, the ©with© statement has the form:
    1299 \begin{cfa}
    1300 $\emph{with-statement}$:
    1301         'with' '(' $\emph{expression-list}$ ')' $\emph{compound-statement}$
    1302 \end{cfa}
    1303 and may appear as the body of a function or nested within a function body.
    1304 Each expression in the expression-list provides a type and object.
    1305 The type must be an aggregate type.
     1320void g( S & s, T & t ) @with ( s, t )@ {        $\C{// multiple aggregate parameters}$
     1321        c;   @s.@i;   d;                                                $\C{// s.c, s.i, s.d}$
     1322        m;   @t.@i;   n;                                                $\C{// t.m, t.i, t.n}$
     1323}
     1324\end{cfa}
     1325where qualification is only necessary to disambiguate the shadowed variable ©i©.
     1326
     1327In detail, the ©with© statement may appear as the body of a function or nested within a function body.
     1328The ©with© clause takes a list of expressions, where each expression provides an aggregate type and object.
    13061329(Enumerations are already opened.)
    1307 The object is the implicit qualifier for the open structure-fields.
    1308 
     1330To open a pointer type, the pointer must be dereferenced to obtain a reference to the aggregate type.
     1331\begin{cfa}
     1332S * sp;
     1333with ( *sp ) { ... }
     1334\end{cfa}
     1335The expression object is the implicit qualifier for the open structure-fields.
     1336\CFA's ability to overload variables \see{\VRef{s:VariableOverload}} and use the left-side of assignment in type resolution means most fields with the same name but different types are automatically disambiguated, eliminating qualification.
    13091337All expressions in the expression list are open in parallel within the compound statement.
    13101338This semantic is different from Pascal, which nests the openings from left to right.
    13111339The difference between parallel and nesting occurs for fields with the same name and type:
    13121340\begin{cfa}
    1313 struct S { int @i@; int j; double m; } s, w;
    1314 struct T { int @i@; int k; int m; } t, w;
    1315 with ( s, t ) {
    1316         j + k; $\C{// unambiguous, s.j + t.k}$
    1317         m = 5.0; $\C{// unambiguous, t.m = 5.0}$
    1318         m = 1; $\C{// unambiguous, s.m = 1}$
    1319         int a = m; $\C{// unambiguous, a = s.i }$
    1320         double b = m; $\C{// unambiguous, b = t.m}$
    1321         int c = s.i + t.i; $\C{// unambiguous, qualification}$
    1322         (double)m; $\C{// unambiguous, cast}$
    1323 }
    1324 \end{cfa}
    1325 For parallel semantics, both ©s.i© and ©t.i© are visible, so ©i© is ambiguous without qualification;
    1326 for nested semantics, ©t.i© hides ©s.i©, so ©i© implies ©t.i©.
    1327 \CFA's ability to overload variables means fields with the same name but different types are automatically disambiguated, eliminating most qualification when opening multiple aggregates.
    1328 Qualification or a cast is used to disambiguate.
    1329 
    1330 There is an interesting problem between parameters and the function-body ©with©, \eg:
     1341struct Q { int @i@; int k; int @m@; } q, w;
     1342struct R { int @i@; int j; double @m@; } r, w;
     1343with ( r, q ) {
     1344        j + k;                                                                  $\C{// unambiguous, r.j + q.k}$
     1345        m = 5.0;                                                                $\C{// unambiguous, q.m = 5.0}$
     1346        m = 1;                                                                  $\C{// unambiguous, r.m = 1}$
     1347        int a = m;                                                              $\C{// unambiguous, a = r.i }$
     1348        double b = m;                                                   $\C{// unambiguous, b = q.m}$
     1349        int c = r.i + q.i;                                              $\C{// disambiguate with qualification}$
     1350        (double)m;                                                              $\C{// disambiguate with cast}$
     1351}
     1352\end{cfa}
     1353For parallel semantics, both ©r.i© and ©q.i© are visible, so ©i© is ambiguous without qualification;
     1354for nested semantics, ©q.i© hides ©r.i©, so ©i© implies ©q.i©.
     1355Pascal nested-semantics is possible by nesting ©with© statements.
     1356\begin{cfa}
     1357with ( r ) {
     1358        i;                                                                              $\C{// unambiguous, r.i}$
     1359        with ( q ) {
     1360                i;                                                                      $\C{// unambiguous, q.i}$
     1361        }
     1362}
     1363\end{cfa}
     1364A cast or qualification can be used to disambiguate variables within a ©with© \emph{statement}.
     1365A cast can be used to disambiguate among overload variables in a ©with© \emph{expression}:
     1366\begin{cfa}
     1367with ( w ) { ... }                                                      $\C{// ambiguous, same name and no context}$
     1368with ( (Q)w ) { ... }                                           $\C{// unambiguous, cast}$
     1369\end{cfa}
     1370Because there is no left-side in the ©with© expression to implicitly disambiguate between the ©w© variables, it is necessary to explicitly disambiguate by casting ©w© to type ©Q© or ©R©.
     1371
     1372Finally, there is an interesting problem between parameters and the function-body ©with©, \eg:
    13311373\begin{cfa}
    13321374void ?{}( S & s, int i ) with ( s ) { $\C{// constructor}$
     
    13441386and implicitly opened \emph{after} a function-body open, to give them higher priority:
    13451387\begin{cfa}
    1346 void ?{}( S & s, int @i@ ) with ( s ) @with( $\emph{\R{params}}$ )@ {
     1388void ?{}( S & s, int @i@ ) with ( s ) @with( $\emph{\R{params}}$ )@ { // syntax not allowed, illustration only
    13471389        s.i = @i@; j = 3; m = 5.5;
    13481390}
    13491391\end{cfa}
    1350 Finally, a cast may be used to disambiguate among overload variables in a ©with© expression:
    1351 \begin{cfa}
    1352 with ( w ) { ... } $\C{// ambiguous, same name and no context}$
    1353 with ( (S)w ) { ... } $\C{// unambiguous, cast}$
    1354 \end{cfa}
    1355 and ©with© expressions may be complex expressions with type reference \see{\VRef{s:References}} to aggregate:
    1356 % \begin{cfa}
    1357 % struct S { int i, j; } sv;
    1358 % with ( sv ) { $\C{// implicit reference}$
    1359 %       S & sr = sv;
    1360 %       with ( sr ) { $\C{// explicit reference}$
    1361 %               S * sp = &sv;
    1362 %               with ( *sp ) { $\C{// computed reference}$
    1363 %                       i = 3; j = 4; $\C{\color{red}// sp--{\textgreater}i, sp--{\textgreater}j}$
    1364 %               }
    1365 %               i = 2; j = 3; $\C{\color{red}// sr.i, sr.j}$
    1366 %       }
    1367 %       i = 1; j = 2; $\C{\color{red}// sv.i, sv.j}$
    1368 % }
    1369 % \end{cfa}
    1370 
    1371 In \Index{object-oriented} programming, there is an implicit first parameter, often names \textbf{©self©} or \textbf{©this©}, which is elided.
    1372 \begin{C++}
    1373 class C {
    1374         int i, j;
    1375         int mem() { $\C{\R{// implicit "this" parameter}}$
    1376                 i = 1; $\C{\R{// this->i}}$
    1377                 j = 2; $\C{\R{// this->j}}$
    1378         }
    1379 }
    1380 \end{C++}
    1381 Since \CFA is non-object-oriented, the equivalent object-oriented program looks like:
    1382 \begin{cfa}
    1383 struct S { int i, j; };
    1384 int mem( S & @this@ ) { $\C{// explicit "this" parameter}$
    1385         @this.@i = 1; $\C{// "this" is not elided}$
    1386         @this.@j = 2;
    1387 }
    1388 \end{cfa}
    1389 but it is cumbersome having to write ``©this.©'' many times in a member.
    1390 
    1391 \CFA provides a ©with© clause/statement \see{Pascal~\cite[\S~4.F]{Pascal}} to elided the "©this.©" by opening a scope containing field identifiers, changing the qualified fields into variables and giving an opportunity for optimizing qualified references.
    1392 \begin{cfa}
    1393 int mem( S & this ) @with( this )@ { $\C{// with clause}$
    1394         i = 1; $\C{\R{// this.i}}$
    1395         j = 2; $\C{\R{// this.j}}$
    1396 }
    1397 \end{cfa}
    1398 which extends to multiple routine parameters:
    1399 \begin{cfa}
    1400 struct T { double m, n; };
    1401 int mem2( S & this1, T & this2 ) @with( this1, this2 )@ {
    1402         i = 1; j = 2;
    1403         m = 1.0; n = 2.0;
    1404 }
    1405 \end{cfa}
    1406 
    1407 The statement form is used within a block:
    1408 \begin{cfa}
    1409 int foo() {
    1410         struct S1 { ... } s1;
    1411         struct S2 { ... } s2;
    1412         @with( s1 )@ { $\C{// with statement}$
    1413                 // access fields of s1 without qualification
    1414                 @with s2@ { $\C{// nesting}$
    1415                         // access fields of s1 and s2 without qualification
    1416                 }
    1417         }
    1418         @with s1, s2@ {
    1419                 // access unambiguous fields of s1 and s2 without qualification
    1420         }
    1421 }
    1422 \end{cfa}
    1423 
    1424 When opening multiple structures, fields with the same name and type are ambiguous and must be fully qualified.
    1425 For fields with the same name but different type, context/cast can be used to disambiguate.
    1426 \begin{cfa}
    1427 struct S { int i; int j; double m; } a, c;
    1428 struct T { int i; int k; int m } b, c;
    1429 with( a, b )
    1430 {
    1431 }
    1432 \end{cfa}
    1433 
    1434 \begin{comment}
    1435 The components in the "with" clause
    1436 
    1437   with a, b, c { ... }
    1438 
    1439 serve 2 purposes: each component provides a type and object. The type must be a
    1440 structure type. Enumerations are already opened, and I think a union is opened
    1441 to some extent, too. (Or is that just unnamed unions?) The object is the target
    1442 that the naked structure-fields apply to. The components are open in "parallel"
    1443 at the scope of the "with" clause/statement, so opening "a" does not affect
    1444 opening "b", etc. This semantic is different from Pascal, which nests the
    1445 openings.
    1446 
    1447 Having said the above, it seems reasonable to allow a "with" component to be an
    1448 expression. The type is the static expression-type and the object is the result
    1449 of the expression. Again, the type must be an aggregate. Expressions require
    1450 parenthesis around the components.
    1451 
    1452   with( a, b, c ) { ... }
    1453 
    1454 Does this now make sense?
    1455 
    1456 Having written more CFA code, it is becoming clear to me that I *really* want
    1457 the "with" to be implemented because I hate having to type all those object
    1458 names for fields. It's a great way to drive people away from the language.
    1459 \end{comment}
     1392This implicit semantic matches with programmer expectation.
     1393
    14601394
    14611395
     
    43454279
    43464280
    4347 \subsection{Overloaded Constant}
     4281\subsection{Constant}
    43484282
    43494283The constants 0 and 1 have special meaning.
     
    43844318
    43854319
    4386 \subsection{Variable Overloading}
     4320\subsection{Variable}
     4321\label{s:VariableOverload}
    43874322
    43884323The overload rules of \CFA allow a programmer to define multiple variables with the same name, but different types.
     
    44274362
    44284363
    4429 \subsection{Operator Overloading}
     4364\subsection{Operator}
    44304365
    44314366\CFA also allows operators to be overloaded, to simplify the use of user-defined types.
     
    56855620\end{cfa}
    56865621&
    5687 \begin{lstlisting}[language=C++]
     5622\begin{C++}
    56885623class Line {
    56895624        float lnth;
     
    57125647Line line1;
    57135648Line line2( 3.4 );
    5714 \end{lstlisting}
     5649\end{C++}
    57155650&
    57165651\begin{lstlisting}[language=Golang]
Note: See TracChangeset for help on using the changeset viewer.