Changeset 5103d7a for doc/generic_types/generic_types.tex
- Timestamp:
- Apr 13, 2017, 10:30:54 AM (7 years ago)
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/generic_types/generic_types.tex
rffc9f5a r5103d7a 510 510 div_t qr = div( 13, 5 ); $\C{// return quotient/remainder aggregate}$ 511 511 int q; 512 double r = remquo( 13.5, 5.2, &q ); $\C{// return re turn remainder, alias quotient}$512 double r = remquo( 13.5, 5.2, &q ); $\C{// return remainder, alias quotient}$ 513 513 \end{lstlisting} 514 514 @div@ aggregates the quotient/remainder in a structure, while @remquo@ aliases a parameter to an argument. … … 516 516 Alternatively, a programming language can directly support returning multiple values, \eg in \CFA: 517 517 \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}$ 520 int q, r; $\C{// overload variable names}$ 521 521 double q, r; 522 522 [ q, r ] = div( 13, 5 ); $\C{// select appropriate div and q, r}$ … … 524 524 \end{lstlisting} 525 525 Clearly, this approach is straightforward to understand and use; 526 therefore, why do most programming languages notsupport this obvious feature or provide it awkwardly?526 therefore, why do few programming languages support this obvious feature or provide it awkwardly? 527 527 The answer is that there are complex consequences that cascade through multiple aspects of the language, especially the type-system. 528 528 This section show these consequences and how \CFA deals with them. … … 531 531 \subsection{Tuple Expressions} 532 532 533 The addition of multiple-return-value (MRV) functionsare useless without a syntax for accepting multiple values at the call-site.533 The addition of multiple-return-value functions (MRVF) are useless without a syntax for accepting multiple values at the call-site. 534 534 The simplest mechanism for capturing the return values is variable assignment, allowing the values to be retrieved directly. 535 535 As 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}. 536 536 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:537 However, 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: 538 538 \begin{lstlisting} 539 539 printf( "%d %d\n", div( 13, 5 ) ); $\C{// return values seperated into arguments}$ … … 547 547 bar( foo( 3 ), foo( 3 ) ); 548 548 \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.549 The 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. 550 550 No combination of @foo@s are an exact match with @bar@'s parameters, so the resolver applies C conversions. 551 551 The 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. … … 554 554 \subsection{Tuple Variables} 555 555 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: 556 An 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. 558 As a consequence, \CFA allows declaration of \emph{tuple variables} that can be initialized from an MRVF, \eg: 558 559 \begin{lstlisting} 559 560 [ int, int ] qr = div( 13, 5 ); $\C{// tuple-variable declaration and initialization}$ … … 606 607 In 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@. 607 608 Finally, 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.609 The 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. 609 610 610 611 … … 634 635 Both kinds of tuple assignment have parallel semantics, so that each value on the left and right side is evaluated before any assignments occur. 635 636 As 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.637 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. 637 638 For example, @[y, x] = 3.14@ performs the assignments @y = 3.14@ and @x = 3.14@, yielding @y == 3.14@ and @x == 3@; 638 639 whereas C cascading assignment @y = x = 3.14@ performs the assignments @x = 3.14@ and @y = x@, yielding @3@ in @y@ and @x@. 639 640 Finally, 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}$ 641 This example shows mass, multiple, and cascading assignment used in one expression: 642 \begin{lstlisting} 643 void f( [int, int] ); 644 f( [x, y] = z = 1.5 ); $\C{// assignments in parameter list}$ 646 645 \end{lstlisting} 647 646 … … 679 678 struct B { int * k; short l; }; 680 679 struct C { int x; A y; B z; } v; 681 v.[x, y.[i, j], z.k]; 680 v.[x, y.[i, j], z.k]; $\C{// [v.x, [v.y.i, v.y.j], v.z.k]}$ 682 681 \end{lstlisting} 683 682 … … 732 731 \begin{lstlisting} 733 732 forall(otype T, dtype U) void f( T x, U * y ); 734 f( [5, "hello"]);733 f( [5, "hello"] ); 735 734 \end{lstlisting} 736 735 where @[5, "hello"]@ is flattened, giving argument list @5, "hello"@, and @T@ binds to @int@ and @U@ binds to @const char@. … … 785 784 Since @sum@\(_0\) does not accept any arguments, it is not a valid candidate function for the call @sum(10, 20, 30)@. 786 785 In 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 match s @sum@\(_0\) and terminates the recursion.786 The process continues, @Params@ is bound to @[]@, requiring an assertion @int sum()@, which matches @sum@\(_0\) and terminates the recursion. 788 787 Effectively, 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))@. 789 788
Note: See TracChangeset
for help on using the changeset viewer.