Changeset 5103d7a


Ignore:
Timestamp:
Apr 13, 2017, 10:30:54 AM (7 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
3fe98b7, ad4d035
Parents:
ffc9f5a
Message:

small fixups in tuples section

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/generic_types/generic_types.tex

    rffc9f5a r5103d7a  
    510510div_t qr = div( 13, 5 );                                        $\C{// return quotient/remainder aggregate}$
    511511int q;
    512 double r = remquo( 13.5, 5.2, &q );                     $\C{// return return remainder, alias quotient}$
     512double r = remquo( 13.5, 5.2, &q );                     $\C{// return remainder, alias quotient}$
    513513\end{lstlisting}
    514514@div@ aggregates the quotient/remainder in a structure, while @remquo@ aliases a parameter to an argument.
     
    516516Alternatively, a programming language can directly support returning multiple values, \eg in \CFA:
    517517\begin{lstlisting}
    518 [ int, int ] div( int num, int den );
    519 [ double, double ] div( double num, double den );
    520 int q, r;
     518[ int, int ] div( int num, int den );           $\C{// return two integers}$
     519[ double, double ] div( double num, double den ); $\C{// return two doubles}$
     520int q, r;                                                                       $\C{// overload variable names}$
    521521double q, r;
    522522[ q, r ] = div( 13, 5 );                                        $\C{// select appropriate div and q, r}$
     
    524524\end{lstlisting}
    525525Clearly, this approach is straightforward to understand and use;
    526 therefore, why do most programming languages not support this obvious feature or provide it awkwardly?
     526therefore, why do few programming languages support this obvious feature or provide it awkwardly?
    527527The answer is that there are complex consequences that cascade through multiple aspects of the language, especially the type-system.
    528528This section show these consequences and how \CFA deals with them.
     
    531531\subsection{Tuple Expressions}
    532532
    533 The addition of multiple-return-value (MRV) functions are useless without a syntax for accepting multiple values at the call-site.
     533The addition of multiple-return-value functions (MRVF) are useless without a syntax for accepting multiple values at the call-site.
    534534The simplest mechanism for capturing the return values is variable assignment, allowing the values to be retrieved directly.
    535535As such, \CFA allows assigning multiple values from a function into multiple variables, using a square-bracketed list of lvalue expressions (as above), called a \emph{tuple}.
    536536
    537 However, functions also use \emph{composition} (nested calls), with the direct consequence that MRV functions must also support composition to be orthogonal with single-return-value (SRV) functions, \eg:
     537However, functions also use \emph{composition} (nested calls), with the direct consequence that MRVFs must also support composition to be orthogonal with single-returning-value functions (SRVF), \eg:
    538538\begin{lstlisting}
    539539printf( "%d %d\n", div( 13, 5 ) );                      $\C{// return values seperated into arguments}$
     
    547547bar( foo( 3 ), foo( 3 ) );
    548548\end{lstlisting}
    549 The type-resolver only has the tuple return-types to resolve the call to @bar@ as the parameters are identical, which involves unifying the possible @foo@ functions with @bar@'s parameter list.
     549The type-resolver only has the tuple return-types to resolve the call to @bar@ as the @foo@ parameters are identical, which involves unifying the possible @foo@ functions with @bar@'s parameter list.
    550550No combination of @foo@s are an exact match with @bar@'s parameters, so the resolver applies C conversions.
    551551The minimal cost is @bar( foo@$_1$@( 3 ), foo@$_2$@( 3 ) )@, giving (@int@, {\color{green}@int@}, @double@) to (@int@, {\color{green}@double@}, @double@) with one {\color{green}safe} (widening) conversion from @int@ to @double@ versus ({\color{red}@double@}, {\color{green}@int@}, {\color{green}@int@}) to ({\color{red}@int@}, {\color{green}@double@}, {\color{green}@double@}) with one {\color{red}unsafe} (narrowing) conversion from @double@ to @int@ and two safe conversions.
     
    554554\subsection{Tuple Variables}
    555555
    556 An important observation from function composition is that new variable names are not required to initialize parameters from an MRV function.
    557 As a consequence, \CFA allows declaration of \emph{tuple variables} that can be initialized from an MRV function, \eg:
     556An important observation from function composition is that new variable names are not required to initialize parameters from an MRVF.
     557\CFA also allows declaration of tuple variables that can be initialized from an MRVF, since it can be awkward to declare multiple variables of different types.
     558As a consequence, \CFA allows declaration of \emph{tuple variables} that can be initialized from an MRVF, \eg:
    558559\begin{lstlisting}
    559560[ int, int ] qr = div( 13, 5 );                         $\C{// tuple-variable declaration and initialization}$
     
    606607In the call to @g@, the values @y@ and @10@ are structured into a single argument of type @[int, int]@ to match the parameter type of @g@.
    607608Finally, in the call to @h@, @x@ is flattened to yield an argument list of length 3, of which the first component of @x@ is passed as the first parameter of @h@, and the second component of @x@ and @y@ are structured into the second argument of type @[int, int]@.
    608 The flexible structure of tuples permits a simple and expressive function call syntax to work seamlessly with both SRV and MRV functions, and with any number of arguments of arbitrarily complex structure.
     609The flexible structure of tuples permits a simple and expressive function call syntax to work seamlessly with both SRVF and MRVF, and with any number of arguments of arbitrarily complex structure.
    609610
    610611
     
    634635Both kinds of tuple assignment have parallel semantics, so that each value on the left and right side is evaluated before any assignments occur.
    635636As a result, it is possible to swap the values in two variables without explicitly creating any temporary variables or calling a function, \eg, @[x, y] = [y, x]@.
    636 This semantics means mass assignment differs from C cascading assignment (\eg @a=b=c@) in that conversions are applied in each individual assignment, which prevents data loss from the chain of conversions that can happen during a cascading assignment.
     637This semantics means mass assignment differs from C cascading assignment (\eg @a = b = c@) in that conversions are applied in each individual assignment, which prevents data loss from the chain of conversions that can happen during a cascading assignment.
    637638For example, @[y, x] = 3.14@ performs the assignments @y = 3.14@ and @x = 3.14@, yielding @y == 3.14@ and @x == 3@;
    638639whereas C cascading assignment @y = x = 3.14@ performs the assignments @x = 3.14@ and @y = x@, yielding @3@ in @y@ and @x@.
    639640Finally, tuple assignment is an expression where the result type is the type of the left-hand side of the assignment, just like all other assignment expressions in C.
    640 This example shows multiple, mass, and cascading assignment used in one expression:
    641 \begin{lstlisting}
    642 int a, b;
    643 double c, d;
    644 [void] f( [int, int] );
    645 f( [c, a] = [b, d] = 1.5 );                                     $\C{// assignments in parameter list}$
     641This example shows mass, multiple, and cascading assignment used in one expression:
     642\begin{lstlisting}
     643void f( [int, int] );
     644f( [x, y] = z = 1.5 );                                          $\C{// assignments in parameter list}$
    646645\end{lstlisting}
    647646
     
    679678struct B { int * k; short l; };
    680679struct C { int x; A y; B z; } v;
    681 v.[x, y.[i, j], z.k];
     680v.[x, y.[i, j], z.k];                                           $\C{// [v.x, [v.y.i, v.y.j], v.z.k]}$
    682681\end{lstlisting}
    683682
     
    732731\begin{lstlisting}
    733732forall(otype T, dtype U) void f( T x, U * y );
    734 f([5, "hello"]);
     733f( [5, "hello"] );
    735734\end{lstlisting}
    736735where @[5, "hello"]@ is flattened, giving argument list @5, "hello"@, and @T@ binds to @int@ and @U@ binds to @const char@.
     
    785784Since @sum@\(_0\) does not accept any arguments, it is not a valid candidate function for the call @sum(10, 20, 30)@.
    786785In order to call @sum@\(_1\), @10@ is matched with @x@, and the argument resolution moves on to the argument pack @rest@, which consumes the remainder of the argument list and @Params@ is bound to @[20, 30]@.
    787 The process continues, @Params@ is bound to @[]@, requiring an assertion @int sum()@, which matchs @sum@\(_0\) and terminates the recursion.
     786The process continues, @Params@ is bound to @[]@, requiring an assertion @int sum()@, which matches @sum@\(_0\) and terminates the recursion.
    788787Effectively, this algorithm traces as @sum(10, 20, 30)@ $\rightarrow$ @10 + sum(20, 30)@ $\rightarrow$ @10 + (20 + sum(30))@ $\rightarrow$ @10 + (20 + (30 + sum()))@ $\rightarrow$ @10 + (20 + (30 + 0))@.
    789788
Note: See TracChangeset for help on using the changeset viewer.