Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/user/user.tex

    rbb20aa6 r3be81a4  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Fri Jul 26 06:56:11 2024
    14 %% Update Count     : 6955
     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 associates 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}
    3359 where the ©?© selects the default value as the argument.
     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}
    33603404Here the missing arguments are inserted from the default values in the parameter list.
    33613405The compiler rewrites missing default values into explicit positional arguments.
     
    33643408\item
    33653409Routines with a large number of parameters are often very generalized, giving a programmer a number of different options on how a computation is performed.
    3366 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.
    33673411Without 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.
    33683412\item
     
    33783422Instead, a default value is used, which may not be the programmer's intent.
    33793423
    3380 Default parameters may only appear in a prototype versus definition context:
    3381 \begin{cfa}
    3382 void f( int x, int y = 2, int z = 3 );  §\C{// prototype: allowed}§
    3383 void f( int, int = 2, int = 3 );                §\C{// prototype: allowed}§
    3384 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}§
    33853429\end{cfa}
    33863430The reason for this restriction is to allow separate compilation.
    3387 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.
    33883461
    33893462Default arguments and overloading \see{\VRef{s:Overloading}} are complementary.
     
    33933466\multicolumn{1}{c@{\hspace{3em}}}{\textbf{default arguments}}   & \multicolumn{1}{c}{\textbf{overloading}}      \\
    33943467\begin{cfa}
    3395 void f( int x, int y = 2, int z = 3 ) {...}
     3468void p( int x, int y = 2, int z = 3 ) {...}
    33963469
    33973470
     
    33993472&
    34003473\begin{cfa}
    3401 void f( int x, int y, int z ) {...}
    3402 void f( int x ) { f( x, 2, 3 ); }
    3403 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 ); }
    34043477\end{cfa}
    34053478\end{tabular}
    34063479\end{cquote}
    34073480the number of required overloaded routines is linear in the number of default values, which is unacceptable growth.
    3408 In general, overloading is used over default parameters, if the body of the routine is significantly different.
    3409 Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list.
    3410 \begin{cfa}
    3411 f( 1, ®?®, 5 );                                                 §\C{// rewrite \(\Rightarrow\) f( 1, 2, 5 )}§
    3412 \end{cfa}
    3413 
    3414 
    3415 \subsection{Named (or Keyword)}
    3416 
    3417 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.
    3418 For example, given the routine prototype:
    3419 \begin{cfa}
    3420 void f( int ®?®x, int ®?®y, int ®?®z );
    3421 \end{cfa}
    3422 allowable calls are:
    3423 \begin{cfa}
    3424 f( ?x = 3, ?y = 4, ?z = 5 );                    §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3425 f( ?y = 4, ?z = 5, ?x = 3 );                    §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3426 f( ?z = 5, ?x = 3, ?y = 4 );                    §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3427 f( ?x = 3, ?z = 5, ?y = 4 );                    §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3428 \end{cfa}
    3429 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.
    3430 The compiler rewrites a named call into a positional call.
    3431 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©.
    3432 The advantages of named parameters are:
    3433 \begin{itemize}
    3434 \item
    3435 Remembering the names of the parameters may be easier than the order in the routine definition.
    3436 \item
    3437 Parameter names provide documentation at the call site (assuming the names are descriptive).
    3438 \item
    3439 Changes can be made to the order or number of parameters without affecting the call (although the call must still be recompiled).
    3440 \end{itemize}
    3441 
    3442 Named parameters may only appear in a prototype versus definition context:
    3443 \begin{cfa}
    3444 void f( int  x, int ?y, int ?z );               §\C{// prototype: allowed}§
    3445 void f( int ?x, int , int ?z );                 §\C{// prototype: allowed}§
    3446 void f( int x, int ?y, int ?z ) ®{}®    §\C{// definition: disallowed}§
    3447 \end{cfa}
    3448 The reason for this restriction is to allow separate compilation.
    3449 Multiple prototypes with different positional parameter names is an error.
    3450 
    3451 The named parameter is not part of type resolution;
    3452 only the type of the expression assigned to the named parameter affects type resolution.
    3453 \begin{cfa}
    3454 int f( int ?i, int ?j );
    3455 int f( int ?i, double ?j );
    3456 f( ?j = 3, ?i = 4 );                                    §\C{// 1st f}§
    3457 f( ?i = 7, ?j = 8.1 );                                  §\C{// 2nd f}§
    3458 \end{cfa}
    3459 
    3460 
    3461 \subsection{Mixed Default/Named}
    3462 
    3463 Default and named parameters can be intermixed and named parameters can have a default value.
    3464 For example, given the routine prototype:
    3465 \begin{cfa}
    3466 void f( int x, int y ®= 1®, int ®?®z ®= 2® );
    3467 \end{cfa}
    3468 allowable calls are:
    3469 \begin{cfa}
    3470 f( 3 );                                                                 §\C{// rewrite \(\Rightarrow\) f( 3, 1, 2 )}§
    3471 f( 3, 4 );                                                              §\C{// rewrite \(\Rightarrow\) f( 3, 4, 2 )}§
    3472 f( 3, ?z = 5 );                                                 §\C{// rewrite \(\Rightarrow\) f( 3, 1, 5 )}§
    3473 f( 3, 4, ?z = 5 );                                              §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3474 f( ?z = 5, 3 );                                                 §\C{// rewrite \(\Rightarrow\) f( 3, 1, 5 )}§
    3475 f( 3, ?z = 5, 4 );                                              §\C{// rewrite \(\Rightarrow\) f( 3, 4, 5 )}§
    3476 \end{cfa}
    3477 Finally, the ellipse (``...'') parameter must appear after positional and named parameters in a routine prototype.
    3478 \begin{cfa}
    3479 void f( int i = 1, int ?j = 2, ®...® );
    3480 \end{cfa}
    3481 
    3482 \CFA named and default arguments are backwards compatible with C.
    3483 \Index*[C++]{\CC{}} only supports default parameters;
    3484 \Index*{Ada} supports both named and default parameters.
     3481In general, overloading should only be used over default arguments if the body of the routine is significantly different.
     3482Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as:
     3483\begin{cfa}
     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.
     3488\Index*[C++]{\CC{}} only supports default arguments;
     3489\Index*{Ada} supports both named and default arguments.
    34853490
    34863491
Note: See TracChangeset for help on using the changeset viewer.