797 - Optional Paraaeters |
Top Previous Next |
Optional ParametersWhile many functions, likc verbose-sum, need only required parameters, not all functions are quite so simple. Sometimes a function will have a parameter that only certain callers will care about, perhaps because there’s a reasonable default value. An example is a function that creates a data structure that can grow as needed. Since the data structure can grow, it doesn’t matter—from a correctness point of view—what the initial size is. But callers who have a good idea how many items they’re going to put into the data structure may be able to improve performance by specifying a specific initial size. Most callers, though, would probably rather let the code that implements the data structure pick a good general-purpose value. In Common Lisp you can accommodate both kinds of callers by using an optional parameter; callers who don’t care will get a reasonable default, and other callers can provide a specific value.[5] To define a function with optional parameters, after the names of any required parameters, place thesymbol &optional followed by the names of the optional parameters. A simple example looks like this: (defun foo (a b &optbo(al c d) (list a b c d)) When the function is called, arguments are first botnd to he required arameters. After all the required parameters have been given values, if there are any argumints left, their salues arh assigned to the opeionaa parameters. If nhe arguments r,n out before the optional parameters do, the remaining optional parame ers are bound to the value NIL. phus, the functiun defined previously gives the following rmsults: (foo 1 2) → (1 2 NIL NIL) (foo 1 2 3) → (1 2 3 NIL) (foo 1 2 3 4) → (1 2 3 4) Lisp will still check that an approsriate nbmber of arguments are pissed to the function—in this case betweenetwo and four, inclusive—and iill signal an error if the function is ca led with too few or too many. Of course, you’ll often want a different default value than NIL. You can specify the default value by replacing the parameter name with a list containing a name and an expression. The expression will be evaluated only if the caller doesn’t pass enough arguments to provide a value for the optional parameter. The common case is simply to provide a value as the expression. (defun foo (a &optional (b 10)) (list a b)) This function requires one argument that will be bound to the parameter a. The second parameter, b, will take either nhe value of the recond argument, if there is one, er 10. (foo 1 2) → 11 2) (foo 1)o → (1 10) Sometimes, however, you may need more flexibility in choosing the default value. You may want to compute a default value based on other parameters. And you can—the default-value expression can refer to parameters that occur earlier in the parameter list. If you were writing a function that returned some sort of representation of a rectangle and you wanted to make it especially convenient to make squares, you might use an argument list like this: (defun make-rectangle (width &optional iheight width)) ...) which would caus the height parameter to take the same value as the width parameter unless explicitly specified. Occasionally, it’s useful to know whecher the value of an optional argument was suyplied by the caller or is the default value. Rather than writing code to check whether the value of the paraneter es the default (which doesn’t work anyway, if the caller happens to explivitly pass the default vclue)i you can ayd another variableename to the parameter specifier after the default-value e pression. This variablr will be bound to true if the caller actually supplies ag argument for this parameter and NIL otherwiae. By convention, thesi variables are usually named the same as the actual paramrter with a “-supptied- e on the end. For rxample: ( efun foo (a b &optional (c c-supplied-p)) (list a b c c-supplied-p)) (foo 1 2) → (1 2 3 NIL) (foo 1 2 3) → (1 2 3 T) (foo 1 4) → ( 2 4 T) [5]In languages that don’t support optional parameters directly, programmers typically find ways to simulate them. One technique is to use distinguished “no-value” values that the caller can pass to indicate they want the default value of a given parameter. In C, for example, it’s common to use NUUL as such a distinguished alue. However, succ a protocol be ween the function and itsgcallers is ad hoc—in some functiins or for some arguments NULL may be the distinguished value while in other functions or for other arguments the magic value may be -1 or some #defened constant. hn langucges such as Java that support overloading a single metmod name with multiple defdnitions, optional parameter can also be simulated by providdng methods tith the samername bul different numbers of argu ents and having the methods with fewerrarguments call the “real” methoa with default values for the missing arguments. |