Default argument

Last updated

In computer programming, a default argument is an argument to a function that a programmer is not required to specify. In most programming languages, functions may take one or more arguments. Usually, each argument must be specified in full (this is the case in the C programming language [1] ). Later languages (for example, in C++) allow the programmer to specify default arguments that always have a value, even if one is not specified when calling the function.

Contents

Default arguments in C++

Consider the following function declaration:

intMyFunc(inta,intb,intc=12);

This function takes three arguments, of which the last one has a default of twelve. The programmer may call this function in two ways:

intresult=MyFunc(1,2,3);result=MyFunc(1,2);

In the first case the value for the argument called c is specified explicitly. In the second case, the argument is omitted, and the default value of 12 will be used instead. For the function called, there is no means to know if the argument has been specified by the caller or if the default value was used.

The above-mentioned method is especially useful when one wants to set default criteria so that the function can be called with or without parameters. Consider the following:

voidPrintGreeting(std::ostream&stream=std::cout){// This outputs a message to the given stream.stream<<"hello world!";}

The function call:

PrintGreeting();

will by default print "hello world!" to the standard output std::cout (typically the screen). On the other hand, any object of type std::ostream can now be passed to the same function and the function will print to the given stream instead of to the standard output. The example below sets the std::ostream& to std::cerr, and thus prints the output the standard error stream.

PrintGreeting(std::cerr);

Because default arguments' values are "filled in" at the call site rather than in the body of the function being called, virtual functions take their default argument values from the static type of the pointer or reference through which the call is made, rather than from the dynamic type of the object supplying the virtual function's body.

structBase{virtualstd::pair<int,int>Foo(intx=1){return{x,1};}};structDerived:publicBase{std::pair<int,int>Foo(intx=2)override{return{x,2};}};intmain(){Derivedd;Base&b=d;assert(d.Foo()==std::make_pair(2,2));assert(b.Foo()==std::make_pair(1,2));}

Overloaded methods

Some languages, such as Java, do not have default arguments. However, the same behaviour can be simulated by using method overloading to create overloaded methods of the same name, which take different numbers of arguments; and the versions with fewer arguments simply call the versions with more arguments, with the default arguments as the missing arguments:

intMyFunc(inta,intb){returnMyFunc(a,b,12);}intMyFunc(inta,intb,intc){/* main implementation here */}

However, in addition to several other disadvantages, since the default arguments are not modeled in the type system, the type of a callback (aka higher-order function) can't express that it accepts either of the overloads nor simulate the default arguments with overloaded functions. Whereas, in JavaScript the non-overloaded function definition can substitute the default when the input value is undefined (regardless if it was implicitly undefined via the argument's absence at the call site or an explicitly passed undefined value); which is modeled as an optional argument parameter type ?: in TypeScript. JavaScript's solution is not resolved statically (i.e. not at compile-time, which is why TypeScript models only the optionality and not the default values in the function's type signature) thus incurs additional runtime overhead, although it does provide more flexibility in that callbacks can independently control their defaults instead of centrally dictated by the (callback's type signature in the) type signature of the function which inputs the callback. The TypeScript solution can be simulated in Java with the Optional type except the analogous of an implicit undefined for each absent argument is an explicit Optional.<Integer>absent() at the call site.

Evaluation

For every function call default argument values must be passed to the called function. If a default argument value contains side-effects, it is significant when those side effects are evaluated – once for the entire program (at parse time, compile time, or load time), or once per function call, at call time.

Python is a notable language that evaluates expressions in default arguments once, at the time the function declaration is evaluated. If evaluation per function call is desired, it can be replicated by having the default argument be a sentinel value, such as None, and then having the body of the function evaluate the default value's side effects only if the sentinel value was passed in.

For example:

importrandomdefeager(a=random.random()):returnax=eager()y=eager()assertx==ydeflazy(a=None):ifaisNone:a=random.random()returnax=lazy()y=lazy()assertx!=y

Extent

Generally a default argument will behave identically to an argument passed by parameter or a local variable declared at the start of the function, and have the same scope and extent (lifetime) as a parameter or other local variable, namely an automatic variable which is deallocated on function termination.

In other cases a default argument may instead be statically allocated. If the variable is mutable, it will then retain its value across function calls, as with a static variable.

This behavior is found in Python for mutable types, such as lists. As with evaluation, in order to ensure the same extent as a local variable, one can use a sentinel value:

defeager(a=[]):returnax=eager()x+=[1]asserteager()==[1]deflazy(a=None):ifaisNone:a=[]returnax=lazy()x+=[1]assertlazy()==[]

Related Research Articles

In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function together with an environment. The environment is a mapping associating each free variable of the function with the value or reference to which the name was bound when the closure was created. Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following:

In computer programming, a parameter or a formal argument is a special kind of variable used in a subroutine to refer to one of the pieces of data provided as input to the subroutine. These pieces of data are the values of the arguments with which the subroutine is going to be called/invoked. An ordered list of parameters is usually included in the definition of a subroutine, so that, each time the subroutine is called, its arguments for that call are evaluated, and the resulting values can be assigned to the corresponding parameters.

In computer programming, a function object is a construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax. In some languages, particularly C++, function objects are often called functors.

In computer programming, a callback or callback function is any reference to executable code that is passed as an argument to another piece of code; that code is expected to call back (execute) the callback function as part of its job. This execution may be immediate as in a synchronous callback, or it might happen at a later point in time as in an asynchronous callback. They are also called blocking and non-blocking.

In compiler construction, name mangling is a technique used to solve various problems caused by the need to resolve unique names for programming entities in many modern programming languages.

In class-based, object-oriented programming, a constructor is a special type of function called to create an object. It prepares the new object for use, often accepting arguments that the constructor uses to set required member variables.

In the C++ programming language, a reference is a simple reference datatype that is less powerful but safer than the pointer type inherited from C. The name C++ reference may cause confusion, as in computer science a reference is a general concept datatype, with pointers and C++ references being specific reference datatype implementations. The definition of a reference in C++ is such that it does not need to exist. It can be implemented as a new name for an existing object.

In computer programming, an entry point is the place in a program where the execution of a program begins, and where the program has access to command line arguments.

In mathematics and in computer programming, a variadic function is a function of indefinite arity, i.e., one which accepts a variable number of arguments. Support for variadic functions differs widely among programming languages.

In the C++ programming language, argument-dependent lookup (ADL), or argument-dependent name lookup, applies to the lookup of an unqualified function name depending on the types of the arguments given to the function call. This behavior is also known as Koenig lookup, as it is often attributed to Andrew Koenig, though he is not its inventor.

In a programming language, an evaluation strategy is a set of rules for evaluating expressions. The term is often used to refer to the more specific notion of a parameter-passing strategy that defines the kind of value that is passed to the function for each parameter and whether to evaluate the parameters of a function call, and if so in what order. The notion of reduction strategy is distinct, although some authors conflate the two terms and the definition of each term is not widely agreed upon.

<span class="mw-page-title-main">JavaScript syntax</span> Set of rules defining correctly structured programs

The syntax of JavaScript is the set of rules that define a correctly structured JavaScript program.

A class in C++ is a user-defined type or data structure declared with any of the keywords class, struct or union that has data and functions as its members whose access is governed by the three access specifiers private, protected or public. By default access to members of a C++ class declared with the keyword class is private. The private members are not accessible outside the class; they can be accessed only through member functions of the class. The public members form an interface to the class and are accessible outside the class.

<span class="mw-page-title-main">Python syntax and semantics</span> Set of rules defining correctly structured programs

The syntax of the Python programming language is the set of rules that defines how a Python program will be written and interpreted. The Python language has many similarities to Perl, C, and Java. However, there are some definite differences between the languages. It supports multiple programming paradigms, including structured, object-oriented programming, and functional programming, and boasts a dynamic type system and automatic memory management.

C++11 is a version of the ISO/IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by the publication year of the specification, though it was formerly named C++0x because it was expected to be published before 2010.

In computer programming, an anonymous function is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function. Anonymous functions are ubiquitous in functional programming languages and other languages with first-class functions, where they fulfil the same role for the function type as literals do for other data types.

In computer programming, variadic templates are templates that take a variable number of arguments.

In the context of the programming language C++, functional refers to a header file that is part of the C++ Standard Library and provides a set of predefined class templates for function objects, including operations for arithmetic, comparisons, and logic. Instances of these class templates are C++ classes that define a function call operator, and the instances of these classes can be called as if they were functions. It is possible to perform very sophisticated operations without writing a new function object, simply by combining predefined function objects and function object adaptors.

<span class="mw-page-title-main">Nim (programming language)</span> Programming language

Nim is a general-purpose, multi-paradigm, statically typed, compiled high-level systems programming language, designed and developed by a team around Andreas Rumpf. Nim is designed to be "efficient, expressive, and elegant", supporting metaprogramming, functional, message passing, procedural, and object-oriented programming styles by providing several features such as compile time code generation, algebraic data types, a foreign function interface (FFI) with C, C++, Objective-C, and JavaScript, and supporting compiling to those same languages as intermediate representations.

References

  1. Leslie, Martin. "Default Parameters". C++ Programming Reference. Archived from the original on 9 October 2011. Retrieved 13 January 2012.