Changes in / [3cb693c:c1b0b8f]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/user/user.tex

    r3cb693c rc1b0b8f  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Thu Jul 25 16:53:43 2024
    14 %% Update Count     : 6945
     13%% Last Modified On : Tue Jul  9 10:43:40 2024
     14%% Update Count     : 6887
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    15981598and implicitly opened \emph{after} a function-body open, to give them higher priority:
    15991599\begin{cfa}
    1600 void f( S & s, char ®c® ) with ( s ) ®with( §\emph{\R{params}}§ )® { // syntax disallowed, illustration only
     1600void f( S & s, char ®c® ) with ( s ) ®with( §\emph{\R{params}}§ )® { // syntax not allowed, illustration only
    16011601        s.c = ®c;®  i = 3;  d = 5.5;
    16021602}
     
    33133313for example, the following is incorrect:
    33143314\begin{cfa}
    3315 * [ int x ] f () fp; §\C{// routine name "f" is disallowed}§
    3316 \end{cfa}
    3317 
    3318 
    3319 \section{Default and Named Parameter}
    3320 
    3321 Default\index{default parameter}\index{parameter!default} and named\index{named parameter}\index{parameter!named} parameters~\cite{Hardgrave76}\footnote{
     3315* [ int x ] f () fp; §\C{// routine name "f" is not allowed}§
     3316\end{cfa}
     3317
     3318
     3319\section{Named and Default Arguments}
     3320
     3321Named\index{named arguments}\index{arguments!named} and default\index{default arguments}\index{arguments!default} arguments~\cite{Hardgrave76}\footnote{
    33223322Francez~\cite{Francez77} proposed a further extension to the named-parameter passing style, which specifies what type of communication (by value, by reference, by name) the argument is passed to the routine.}
    33233323are two mechanisms to simplify routine call.
    3324 
    3325 
    3326 \subsection{Default}
    3327 
    3328 A default parameter provides the ability to associate a default value with a parameter so it can be optionally specified in the argument list.
    3329 For example, given the routine prototype:
    3330 \begin{cfa}
    3331 void f( int x ®= 1®, int y ®= 2®, int z ®= 3® );
    3332 \end{cfa}
    3333 allowable calls are:
    3334 \begin{cquote}
    3335 \setlength{\tabcolsep}{0.75in}
    3336 \begin{tabular}{@{}ll@{}}
    3337 \textbf{positional arguments} & \textbf{empty arguments} \\
    3338 \begin{cfa}
    3339 f(); §\C[0.75in]{// rewrite \(\Rightarrow\) f( 1, 2, 3 )}§
    3340 f( 4 ); §\C{// rewrite \(\Rightarrow\) f( 4, 2, 3 )}§
    3341 f( 4, 4 ); §\C{// rewrite \(\Rightarrow\) f( 4, 4, 3 )}§
    3342 f( 4, 4, 4 ); §\C{// rewrite \(\Rightarrow\) f( 4, 4, 4 )}\CRT§
    3343 
    3344 
    3345 
    3346 \end{cfa}
    3347 &
    3348 \begin{cfa}
    3349 f( ?, 4, 4 ); §\C[1.0in]{// rewrite \(\Rightarrow\) f( 1, 4, 4 )}§
    3350 f( 4, ?, 4 ); §\C{// rewrite \(\Rightarrow\) f( 4, 2, 4 )}§
    3351 f( 4, 4, ? ); §\C{// rewrite \(\Rightarrow\) f( 4, 4, 3 )}§
    3352 f( 4, ?, ? ); §\C{// rewrite \(\Rightarrow\) f( 4, 2, 3 )}§
    3353 f( ?, 4, ? ); §\C{// rewrite \(\Rightarrow\) f( 1, 4, 3 )}§
    3354 f( ?, ?, 4 ); §\C{// rewrite \(\Rightarrow\) f( 1, 2, 4 )}§
    3355 f( ?, ?, ? ); §\C{// rewrite \(\Rightarrow\) f( 1, 2, 3 )}\CRT§
    3356 \end{cfa}
    3357 \end{tabular}
    3358 \end{cquote}
     3324Both mechanisms are discussed with respect to \CFA.
     3325\begin{description}
     3326\item[Named (or Keyword) Arguments:]
     3327provide the ability to specify an argument to a routine call using the parameter name rather than the position of the parameter.
     3328For example, given the routine:
     3329\begin{cfa}
     3330void p( int x, int y, int z ) {...}
     3331\end{cfa}
     3332a positional call is:
     3333\begin{cfa}
     3334p( 4, 7, 3 );
     3335\end{cfa}
     3336whereas a named (keyword) call may be:
     3337\begin{cfa}
     3338p( z : 3, x : 4, y : 7 );  §\C{// rewrite \(\Rightarrow\) p( 4, 7, 3 )}§
     3339\end{cfa}
     3340Here the order of the arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters.
     3341The compiler rewrites a named call into a positional call.
     3342The advantages of named parameters are:
     3343\begin{itemize}
     3344\item
     3345Remembering the names of the parameters may be easier than the order in the routine definition.
     3346\item
     3347Parameter names provide documentation at the call site (assuming the names are descriptive).
     3348\item
     3349Changes can be made to the order or number of parameters without affecting the call (although the call must still be recompiled).
     3350\end{itemize}
     3351
     3352Unfortunately, named arguments do not work in C-style programming-languages because a routine prototype is not required to specify parameter names, nor do the names in the prototype have to match with the actual definition.
     3353For example, the following routine prototypes and definition are all valid.
     3354\begin{cfa}
     3355void p( int, int, int ); §\C{// equivalent prototypes}§
     3356void p( int x, int y, int z );
     3357void p( int y, int x, int z );
     3358void p( int z, int y, int x );
     3359void p( int q, int r, int s ) {} §\C{// match with this definition}§
     3360\end{cfa}
     3361Forcing matching parameter names in routine prototypes with corresponding routine definitions is possible, but goes against a strong tradition in C programming.
     3362Alternatively, prototype definitions can be eliminated by using a two-pass compilation, and implicitly creating header files for exports.
     3363The former is easy to do, while the latter is more complex.
     3364
     3365Furthermore, named arguments do not work well in a \CFA-style programming-languages because they potentially introduces a new criteria for type matching.
     3366For example, it is technically possible to disambiguate between these two overloaded definitions of ©f© based on named arguments at the call site:
     3367\begin{cfa}
     3368int f( int i, int j );
     3369int f( int x, double y );
     3370
     3371f( j : 3, i : 4 ); §\C{// 1st f}§
     3372f( x : 7, y : 8.1 ); §\C{// 2nd f}§
     3373f( 4, 5 );  §\C{// ambiguous call}§
     3374\end{cfa}
     3375However, named arguments compound routine resolution in conjunction with conversions:
     3376\begin{cfa}
     3377f( i : 3, 5.7 ); §\C{// ambiguous call ?}§
     3378\end{cfa}
     3379Depending on the cost associated with named arguments, this call could be resolvable or ambiguous.
     3380Adding named argument into the routine resolution algorithm does not seem worth the complexity.
     3381Therefore, \CFA does \emph{not} attempt to support named arguments.
     3382
     3383\item[Default Arguments]
     3384provide the ability to associate a default value with a parameter so it can be optionally specified in the argument list.
     3385For example, given the routine:
     3386\begin{cfa}
     3387void p( int x = 1, int y = 2, int z = 3 ) {...}
     3388\end{cfa}
     3389the allowable positional calls are:
     3390\begin{cfa}
     3391p(); §\C{// rewrite \(\Rightarrow\) p( 1, 2, 3 )}§
     3392p( 4 ); §\C{// rewrite \(\Rightarrow\) p( 4, 2, 3 )}§
     3393p( 4, 4 ); §\C{// rewrite \(\Rightarrow\) p( 4, 4, 3 )}§
     3394p( 4, 4, 4 ); §\C{// rewrite \(\Rightarrow\) p( 4, 4, 4 )}§
     3395// empty arguments
     3396p(  , 4, 4 ); §\C{// rewrite \(\Rightarrow\) p( 1, 4, 4 )}§
     3397p( 4,  , 4 ); §\C{// rewrite \(\Rightarrow\) p( 4, 2, 4 )}§
     3398p( 4, 4,   ); §\C{// rewrite \(\Rightarrow\) p( 4, 4, 3 )}§
     3399p( 4,  ,   ); §\C{// rewrite \(\Rightarrow\) p( 4, 2, 3 )}§
     3400p(  , 4,   ); §\C{// rewrite \(\Rightarrow\) p( 1, 4, 3 )}§
     3401p(  ,  , 4 ); §\C{// rewrite \(\Rightarrow\) p( 1, 2, 4 )}§
     3402p(  ,  ,   ); §\C{// rewrite \(\Rightarrow\) p( 1, 2, 3 )}§
     3403\end{cfa}
    33593404Here the missing arguments are inserted from the default values in the parameter list.
    33603405The compiler rewrites missing default values into explicit positional arguments.
     
    33633408\item
    33643409Routines with a large number of parameters are often very generalized, giving a programmer a number of different options on how a computation is performed.
    3365 For many of these routines, there are standard or default settings that work for the majority of computations.
     3410For many of these kinds of routines, there are standard or default settings that work for the majority of computations.
    33663411Without default values for parameters, a programmer is forced to specify these common values all the time, resulting in long argument lists that are error prone.
    33673412\item
     
    33773422Instead, a default value is used, which may not be the programmer's intent.
    33783423
    3379 Default parameters may only appear in a prototype versus definition context:
    3380 \begin{cfa}
    3381 void f( int x, int y = 2, int z = 3 );  §\C{// prototype: allowed}§
    3382 void f( int, int = 2, int = 3 );                §\C{// prototype: allowed}§
    3383 void f( int x, int y = 2, int z = 3 ) ®{}® §\C{// definition: disallowed}§
     3424Default values may only appear in a prototype versus definition context:
     3425\begin{cfa}
     3426void p( int x, int y = 2, int z = 3 ); §\C{// prototype: allowed}§
     3427void p( int, int = 2, int = 3 ); §\C{// prototype: allowed}§
     3428void p( int x, int y = 2, int z = 3 ) {} §\C{// definition: not allowed}§
    33843429\end{cfa}
    33853430The reason for this restriction is to allow separate compilation.
    3386 Multiple prototypes with different default values is undefined.
     3431Multiple prototypes with different default values is an error.
     3432\end{description}
     3433
     3434Ellipse (``...'') arguments present problems when used with default arguments.
     3435The conflict occurs because both named and ellipse arguments must appear after positional arguments, giving two possibilities:
     3436\begin{cfa}
     3437p( /* positional */, ... , /* named */ );
     3438p( /* positional */, /* named */, ... );
     3439\end{cfa}
     3440While it is possible to implement both approaches, the first possibly is more complex than the second, \eg:
     3441\begin{cfa}
     3442p( int x, int y, int z, ... );
     3443p( 1, 4, 5, 6, z : 3, y : 2 ); §\C{// assume p( /* positional */, ... , /* named */ );}§
     3444p( 1, z : 3, y : 2, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§
     3445\end{cfa}
     3446In the first call, it is necessary for the programmer to conceptually rewrite the call, changing named arguments into positional, before knowing where the ellipse arguments begin.
     3447Hence, this approach seems significantly more difficult, and hence, confusing and error prone.
     3448In the second call, the named arguments separate the positional and ellipse arguments, making it trivial to read the call.
     3449
     3450The problem is exacerbated with default arguments, \eg:
     3451\begin{cfa}
     3452void p( int x, int y = 2, int z = 3... );
     3453p( 1, 4, 5, 6, z : 3 ); §\C{// assume p( /* positional */, ... , /* named */ );}§
     3454p( 1, z : 3, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§
     3455\end{cfa}
     3456The first call is an error because arguments 4 and 5 are actually positional not ellipse arguments;
     3457therefore, argument 5 subsequently conflicts with the named argument z : 3.
     3458In the second call, the default value for y is implicitly inserted after argument 1 and the named arguments separate the positional and ellipse arguments, making it trivial to read the call.
     3459For these reasons, \CFA requires named arguments before ellipse arguments.
     3460Finally, while ellipse arguments are needed for a small set of existing C routines, like ©printf©, the extended \CFA type system largely eliminates the need for ellipse arguments \see{\VRef{s:Overloading}}, making much of this discussion moot.
    33873461
    33883462Default arguments and overloading \see{\VRef{s:Overloading}} are complementary.
     
    33923466\multicolumn{1}{c@{\hspace{3em}}}{\textbf{default arguments}}   & \multicolumn{1}{c}{\textbf{overloading}}      \\
    33933467\begin{cfa}
    3394 void f( int x, int y = 2, int z = 3 ) {...}
     3468void p( int x, int y = 2, int z = 3 ) {...}
    33953469
    33963470
     
    33983472&
    33993473\begin{cfa}
    3400 void f( int x, int y, int z ) {...}
    3401 void f( int x ) { f( x, 2, 3 ); }
    3402 void f( int x, int y ) { f( x, y, 3 ); }
     3474void p( int x, int y, int z ) {...}
     3475void p( int x ) { p( x, 2, 3 ); }
     3476void p( int x, int y ) { p( x, y, 3 ); }
    34033477\end{cfa}
    34043478\end{tabular}
    34053479\end{cquote}
    34063480the number of required overloaded routines is linear in the number of default values, which is unacceptable growth.
    3407 In general, overloading is used over default parameters, if the body of the routine is significantly different.
     3481In general, overloading should only be used over default arguments if the body of the routine is significantly different.
    34083482Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as:
    34093483\begin{cfa}
    3410 f( 1, ?, 5 );                                                   §\C{// rewrite \(\Rightarrow\) f( 1, 2, 5 )}§
    3411 \end{cfa}
    3412 
    3413 
    3414 \subsection{Named (or Keyword)}
    3415 
    3416 A named (keyword) parameter provides the ability to specify an argument to a routine call using the parameter name rather than the position of the parameter.
    3417 For example, given the routine prototype:
    3418 \begin{cfa}
    3419 void f( int ®?®x, int ®?®y, int ®?®z );
    3420 \end{cfa}
    3421 allowable calls are:
    3422 \begin{cfa}
    3423 f( ?x = 3, ?y = 4, ?z = 5 );                    §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3424 f( ?y = 4, ?z = 5, ?x = 3 );                    §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3425 f( ?z = 5, ?x = 3, ?y = 4 );                    §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3426 f( ?x = 3, ?z = 5, ?y = 4 );                    §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3427 \end{cfa}
    3428 Here the ordering of the the parameters and arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters.
    3429 The compiler rewrites a named call into a positional call.
    3430 Note, the syntax ©?x = 3© is necessary for the argument, because ©x = 3© has an existing meaning, \ie assign ©3© to ©x© and pass the value of ©x©.
    3431 The advantages of named parameters are:
    3432 \begin{itemize}
    3433 \item
    3434 Remembering the names of the parameters may be easier than the order in the routine definition.
    3435 \item
    3436 Parameter names provide documentation at the call site (assuming the names are descriptive).
    3437 \item
    3438 Changes can be made to the order or number of parameters without affecting the call (although the call must still be recompiled).
    3439 \end{itemize}
    3440 
    3441 Named parameters may only appear in a prototype versus definition context:
    3442 \begin{cfa}
    3443 void f( int  x, int ?y, int ?z );               §\C{// prototype: allowed}§
    3444 void f( int ?x, int , int ?z );                 §\C{// prototype: allowed}§
    3445 void f( int x, int ?y, int ?z ) ®{}®    §\C{// definition: disallowed}§
    3446 \end{cfa}
    3447 The reason for this restriction is to allow separate compilation.
    3448 Multiple prototypes with different positional parameter names is an error.
    3449 
    3450 The named parameter is not part of type resolution;
    3451 the type of the expression assigned to the named parameter affects type resolution.
    3452 \begin{cfa}
    3453 int f( int ?i, int ?j );
    3454 int f( int ?i, double ?j );
    3455 f( ?j = 3, ?i = 4 );                                    §\C{// 1st f}§
    3456 f( ?i = 7, ?j = 8.1 );                                  §\C{// 2nd f}§
    3457 \end{cfa}
    3458 
    3459 
    3460 \subsection{Mixed Default/Named}
    3461 
    3462 Default and named parameters can be intermixed and named parameters can have a default value.
    3463 For example, given the routine prototype:
    3464 \begin{cfa}
    3465 void f( int x, int y ®= 1®, int ®?®z ®= 2® );
    3466 \end{cfa}
    3467 allowable calls are:
    3468 \begin{cfa}
    3469 f( 3 );                                                                 §\C{// rewrite \(\Rightarrow\) f( 3, 1, 2 )}§
    3470 f( 3, 4 );                                                              §\C{// rewrite \(\Rightarrow\) f( 3, 4, 2 )}§
    3471 f( 3, ?z = 5 );                                                 §\C{// rewrite \(\Rightarrow\) f( 3, 1, 5 )}§
    3472 f( 3, 4, ?z = 5 );                                              §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3473 f( ?z = 5, 3 );                                                 §\C{// rewrite \(\Rightarrow\) f( 3, 1, 5 )}§
    3474 f( 3, ?z = 5, 4 );                                              §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3475 \end{cfa}
    3476 Finally, the ellipse (``...'') parameter must appear after positional and named parameters in a routine prototype.
    3477 \begin{cfa}
    3478 void f( int i = 1, int ?j = 2, ®...® );
    3479 \end{cfa}
    3480 
    3481 \CFA named and default arguments are backwards compatible with C.
     3484p( 1, /* default */, 5 ); §\C{// rewrite \(\Rightarrow\) p( 1, 2, 5 )}§
     3485\end{cfa}
     3486
     3487Given the \CFA restrictions above, both named and default arguments are backwards compatible.
    34823488\Index*[C++]{\CC{}} only supports default arguments;
    34833489\Index*{Ada} supports both named and default arguments.
Note: See TracChangeset for help on using the changeset viewer.