CINXE.COM
Named parameters
<html> <head><script type="text/javascript" src="https://web-static.archive.org/_static/js/bundle-playback.js?v=7YQSqjSh" charset="utf-8"></script> <script type="text/javascript" src="https://web-static.archive.org/_static/js/wombat.js?v=txqj7nKC" charset="utf-8"></script> <script>window.RufflePlayer=window.RufflePlayer||{};window.RufflePlayer.config={"autoplay":"on","unmuteOverlay":"hidden"};</script> <script type="text/javascript" src="https://web-static.archive.org/_static/js/ruffle/ruffle.js"></script> <script type="text/javascript"> __wm.init("https://web.archive.org/web"); __wm.wombat("http://plg.uwaterloo.ca:80/~rgesteve/cforall/named_pars.html","20070502112455","https://web.archive.org/","web","https://web-static.archive.org/_static/", "1178105095"); </script> <link rel="stylesheet" type="text/css" href="https://web-static.archive.org/_static/css/banner-styles.css?v=p7PEIJWi" /> <link rel="stylesheet" type="text/css" href="https://web-static.archive.org/_static/css/iconochive.css?v=3PDvdIFv" /> <!-- End Wayback Rewrite JS Include --> <title>Named parameters</title></head> <body> <h1>Named parameters</h1> <p>Named (or <em>keyword</em>) parameters were adopted as a desirable extension to programming languages in the midst fo the "structured programming" frenzy in the 1970s. They address the shortcomings of the traditional scheme of parameter communication, the so-called <em>positional</em> method, still used in most programming languages. <p>In some programming languages, the positional approach takes the form of actually using the position in nominal fashion, like so (in <code>bash</code>): <pre> #!/bin/bash function foo { echo $1 } </pre> The rationale for this particular communication style, in shell scripting, is that arguments, within funtions, are treated in the same manner as arguments given to the script as a whole. </p> <!--- problems with the positional approach ---> <p>Despite its popularity, On occasion this approach might be a shortcoming from a software documentation point of view. Consider the function: float line(float x, float m, float b){ return(m*x + b); } For a programmer using the function, it's not immediate the identification of which parameter is which, and the fact that all of the parameters are of the same type makes matters even worse. Even if modern IDEs provide enough information while writing the program, for someone reading it later on, the meaning of a call such as line(3.2, 8.2, 1.0); might not be readily apparent. When the number of parameters increases, this situation might become a sizable hurdle for the readers of the program.</p> <p>Furthermore, if, at some point during the maintenance process, the function <code>line</code> is modified so that it takes another parameter, without significantly affecting the code for the rest of the parameters, <em>every</em> call to <code>line</code> has to be modified, which can become a drag.</p> <!--- how to solve them (via keyword parameters) ---> <p>Although this situation might be alleviated with a number of techniques involving programming conventions and their disciplined use (designing libraries with a convened upon meaning of their arguments, or using suitably named temporary variables and then calling the function on them), it's probably a good idea to provide a language extension to enforce this discipline to some extent.</p> <p>The addition of the named parameters mechanisms has the added value of allowing the introduction of <em>default values</em> to some or all of them. It was actually been argued that the real power of the named parameter approach is realized when defaults are introduced <a href="#refs.hard">[Hard76]</a>. Defaults allow to provide values to parameters that are not explicitly bound in the call point.</p> <a href="#refs.francez">Francez</a> has 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 function. <h2>Disadvantages</h2> <p>There are some instances where keyword communication is inferior to positional. The most obvious is the call to a procedure that is defined having only a single parameter. The keyword is, of course, unnecessary. Generally, keywording without defaults will require more keystrokes; keywording with defaults will require less. For some of today's machines, the processing of keyword sequences will be somwhat more expensive than the processing of positional sequences. The most disturbing disadvantage may be that an unintantional omission of a parameter on the programmer's part might lead to a program executing incorrectly, but without noticeable errors, since the default value for the parameter would be used.</p> <h2>Case Studies</h2> <h3>C family</h3> <p>In keeping with the spirit of syntax compactness, C, C++ and Java functions only have positional parameters. C++ allows the specification of default values to some or all of the arguments of a function. <h3>The Pascal langauges</h3> <h4>Ada</h4> <p>An Ada function call can look like this (using the above example): line(x => 3.2, m => 8.2, b => 1.0); where the identifier to the left of the '=>' is the <em>name</em> of the parameter, an must match one of the formal parameter names given in the definition of the function (and the value associated with said identifier must be of the same type in the definition). (In addition, parameter lists can have default values, which further enhances both readability and usage). The actual parameter value is then used as the value of the formal parameter with the same name, regardless of its position in the actual argument list in the function application.</p> <p>In Ada, a combination of positional and keyword parameters can be supplied, as long as the latter appear later than the former (in the absence of the default-value facility, a value for <em>all</em> of the formal parameters must be provided)</p> <h4>Euclid</h4> <h3>Statistical Languages (S, S+ and R)</h3> <h2>Implementation in CForAll</h2> <h3>Issues</h3> <ul> <li>Parameters may be passed positionally or by keyword ? <li>Can keyword and positional arguments be freely mixed? (Does this has the same effect as if all the positional arguments came before the keyword ones?) <li>How to deal with unlimited number of parameters ("..."), or "rest" parameters? <li> Can formal parameters can be given default expressions? can parameters with defaults be omitted? <li> <em>More importantly</em>: can overloading resolution deal with all these variants? </ul> <!-- How can lisp-style keyword parameter passing be implemented efficiently? --> <p>Actual parameters can be sorted so that the positional parameters appear before the keyword parameters, and the keyword parameters are in lexicographic order. (Do this as well in the function definition). This is legitimate because the order of evaluation of arguments isn't defined (I hope... I have to look into that). <!-- we can use a linear merge to distribute the keyword parameter values to the appropriate slots. --> </body> </html> <!-- Option 3 - Mixed Clauses This approach is fairly common in database languages and somewhat resembles Smalltalk's messages. Any mandatory parameters come first, and the rest are optional clauses. Examples: Open "Clients" // Minimum is table name Open "Clients" readonly shared Open "Clients" shared readonly // position not matter Open "Clients" _shared _readonly // with underscores Select * from Clients Where status = "M" // SQL Select("*" _from "Clients" _where "status = 'M'") // variation Some of the examples use an underscore to indicate a clause. This is to distinguish between the clauses and the "parameter" of the clauses. Thus, you can have a kind of "sub-parameter", such as the criteria ('status = M') after the _where clause in the last example. Note that the "_shared" clause does not have any sub-parameters because it provides information by itself. This provides two ways to possibly specify some types of parameters: Open "cleints" _shared off Open "clients" _noshare // means the same thing Open "clients" _exclusive // same as no-share Note that if there are more than one mandatory parameters, they are separated by a comma in traditional fashion: foo("this", "that", "pat" _thingy "stuff") foo("this", "that", "pat") The first 3 parameters are mandatory. Thus, those who don't like to program clauses can stay with the familiar, assuming the built-in functions do not use them. --> One possible way to implement the processing of these types of parameters in the callee routine is presented at this link. It uses a function called Clause(). Clause() with one parameter simply is a boolean for it's existence. With two parameters it returns the sub-parameter(s) if the given clause. For example, for an SQL-like statement, Clause("Where") would return True if there is a Where clause, and Clause("Where",1) would return something like "status = 'M'". Note that there are other variations that allow for an unknown quantity of parameters, such as field lists. Of course, field names could be put into one big string instead. There are many ways to skin a cat. The final choice usually depends on the orientation of the language. An advantage of this approach is that it can easily be expanded to allow zero or many sub-parameters per clauses if the language builder later decides to add these features. * Pro - Good compromise between positional and named. Can handle both types of parameters. Can also handle non-parametered clauses and potentially multiple sub-parameters per clause. * Con - May be a bit difficult or slow to parse. Not very common outside of database languages, so it may cause some confusion. Option 4 - Mixed Named Parameters This is very similar to mixed clauses. Example: rr(1, 2, "m") rr(1, y=2) rr(m, y=n) rr(1) rr(x=1, y=7, z="hey") rr(y=7, z="hey", x=1) // The subroutine definition sub rr(x=0, y=0, z="a") ... endsub This example shows the subroutine definition with defaults assigned. (Defaults are addressed in the Parameter Receiving section.) * Pro - Good compromise between positional and named. Can handle both types of parameters. Easy to specify defaults. * Con - Allows exactly one parameter per parameter name. (Contrast this with clauses, which can potentially have zero or many sub-parameters per clause.) Favorite We chose either of the mixed parameter types for their versatility, although we lean toward the mixed clause approach for its expandability. procedure ACTIVATE (PROCESS : in PROCESS_NAME; AFTER : in PROCESS_NAME := NO_PROCESS; WAIT : in DURATION := 0.0; PRIOR : in BOOLEAN := FALSE); As shown in this declaration, the parameter PROCESS must be provided in all calls (because no default expression is given). On the other hand the parameters AFTER, WAIT and PRIOR may be omitted. Thus the two following calls of ACTIVATE are equivalent: ACTIVATE(PROCESS => X, AFTER => NO_PROCESS, WAIT => 0.0, PRIOR => FALSE); ACTIVATE(PROCESS => X); Clearly in many contexts the order of parameters is either highly conventional (as for coordinate systems) or immaterial (as in MAX(X,Y)). Hence Ada admits both conventions. The classical positional notation may be used whenever the programmer feels that named parameters would add verbosity without any gain in readability. The two notations may also be combined, with positional parameters appearing first; that is, once naming is used the rest of the call must use naming. This allows the default value mechanism to be used even when positional notation is desirable, as in the following examples from graph plotting and simulation: MOVE_PEN(X1, Y1, LINE => THICK); MOVE_PEN(X2, Y2, PEN => UP); ACTIVATE(X); ACTIVATE(X, AFTER => Y); ACTIVATE(X, WAIT => 50*SECONDS, PRIOR => TRUE); As shown in this last example, the named notation may be used in conjunction with the default parameters to provide a high degree of expressivity and readability. For the activate primitive in Simula, this could only be achieved at the expense of predefined syntax. Finally the default parameter facility can be used in conjunction with overloading, thereby allowing further possibilities. These are illustrated by the declarations of PUT in the generic package INTEGER_IO: procedure PUT (FILE : in FILE_TYPE; ITEM : in NUM; WIDTH : in FIELD := DEFAULT_WIDTH; BASE : in NUMBER_BASE := DEFAULT_BASE); procedure PUT (ITEM : in NUM; WIDTH : in FIELD := DEFAULT_WIDTH; BASE : in NUMBER_BASE := DEFAULT_BASE); Given the declarations F : FILE; N : NUM; we can issue the following procedure calls for output on the file F: PUT(F, N, 10, 8); -- width 10, octal base PUT(F, N, WIDTH => 10, BASE => 8); -- more explicitly PUT(F, N); -- default width, decimal base We can also issue similar calls for output on the current default output file: PUT(N, 10, 8); PUT(N, WIDTH => 10, BASE => 8); PUT(N); Overloading and default parameters are complementary: In theory, we could achieve the desired flexibility of procedure calls by means of overloading, but this would require a procedure declaration for each possible form of call (eight instead of two in the above example). On the other hand default parameters provide a concise - and thereby convenient - formulation. But - as the above example shows - if we want to omit the first parameter without using named associations, this will have to be achieved by overloading. The example of the two PUT procedures further illustrates that the default expressions need not be static: DEFAULT_WIDTH and DEFAULT_BASE are variables. Another example of the dynamic computation of default expressions is provided by the following procedure ADMISSION: Admission requires a key, a new one being allocated by default in the absence of an explicit one: procedure ADMISSION(K : in KEY_NAME := new KEY); <h1>References</h1> <dl> <dt>[Har 76]</dt> <dd>Hardgrave, W.T., Positional versus keyword parameter communication in programming language, ACM, SIGPLAN Notices 11,5 (May 1976), pp. 52-58.</dd> <dt>[Fr 77]</td> <dd>Francez, N., Another advantage of Keyword Notation for Parameter Communication with Subprograms, Comm. ACM 20,8 (Aug. 1977), pp. 604-605.</dd> </dl> <!-- Using Java reflection to automate extension language parsing Dale Parson ACM SIGPLAN Notices , Proceedings of the 2nd conference on Domain-specific languages January 2000 [Hi 63] Higman,B. What everybody should know about Algol. Computer Journal 6,1 (1963), pp. 50-56. --> </body> </html><!-- FILE ARCHIVED ON 11:24:55 May 02, 2007 AND RETRIEVED FROM THE INTERNET ARCHIVE ON 18:59:07 Feb 21, 2025. JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE. ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C. SECTION 108(a)(3)). --> <!-- playback timings (ms): captures_list: 0.398 exclusion.robots: 0.019 exclusion.robots.policy: 0.012 esindex: 0.006 cdx.remote: 29.666 LoadShardBlock: 282.217 (3) PetaboxLoader3.datanode: 852.967 (4) load_resource: 843.333 PetaboxLoader3.resolve: 86.149 -->