Setting Up Functions with Optional Arguments

When you define a complicated function, you will often want to let some of the arguments of the function be "optional". If you do not give those arguments explicitly, you want them to take on certain "default" values.

Built-in Wolfram Language functions use two basic methods for dealing with optional arguments. You can choose between the same two methods when you define your own functions in the Wolfram Language.

The first method is to have the meaning of each argument determined by its position, and then to allow one to drop arguments, replacing them by default values. Almost all built-in Wolfram Language functions that use this method drop arguments from the end. For example, the built-in function (RefLink[Flatten, paclet:ref/Flatten])[list,n] allows you to drop the second argument, which is taken to have a default value of (RefLink[Infinity, paclet:ref/Infinity]).

You can implement this kind of "positional" argument using _: patterns.

Defining a function with positional arguments.

This defines a function with an optional second argument. When the second argument is omitted, it is taken to have the default value (RefLink[Infinity, paclet:ref/Infinity]):

f[list_,n_:Infinity]:=f0[list,n]

Here is a function with two optional arguments:

fx[list_,n1_:1,n2_:2]:=fx0[list,n1,n2]

The Wolfram Language assumes that arguments are dropped from the end. As a result m here gives the value of n1, while n2 has its default value of 2:

fx[k,m]

The second method that built-in Wolfram Language functions use for dealing with optional arguments is to give explicit names to the optional arguments, and then to allow their values to be given using transformation rules. This method is particularly convenient for functions like (RefLink[Plot, paclet:ref/Plot]) which have a very large number of optional parameters, only a few of which usually need to be set in any particular instance.

The typical arrangement is that values for "named" optional arguments can be specified by including the appropriate transformation rules at the end of the arguments to a particular function. Thus, for example, the rule (RefLink[Joined, paclet:ref/Joined])->(RefLink[True, paclet:ref/True]), which specifies the setting for the named optional argument (RefLink[Joined, paclet:ref/Joined]), could appear as (RefLink[ListPlot, paclet:ref/ListPlot])[list,(RefLink[Joined, paclet:ref/Joined])->(RefLink[True, paclet:ref/True])].

When you set up named optional arguments for a function f, it is conventional to store the default values of these arguments as a list of transformation rules assigned to (RefLink[Options, paclet:ref/Options])[f].

Named arguments.

This sets up default values for two named optional arguments opt1 and opt2 in the function fn:

Options[fn]={opt1->1,opt2->2}

Here is the definition for a function fn which allows zero or more named optional arguments to be specified:

fn[x_,OptionsPattern[]]:=k[x,OptionValue[opt2]]

With no optional arguments specified, the default rule for opt2 is used:

fn[4]

If you explicitly give a rule for opt2, it will override the default rules stored in (RefLink[Options, paclet:ref/Options])[fn]:

fn[4,opt2->7]

Filtering options.

Sometimes when you write a function you will want to pass on options to functions that it calls.

Here is a simple function that solves a differential equation numerically and plots its solution:

odeplot[de_, y_, {x_, x0_, x1_}, opts:OptionsPattern[]] := 
Module[{sol},
sol = NDSolve[de, y, {x,x0,x1}, FilterRules[{opts}, Options[NDSolve]]];
If[Head[sol] === NDSolve,
$Failed,
Plot[Evaluate[y /. sol],{x,x0,x1}, Evaluate[FilterRules[{opts}, Options[Plot]]]]
]
]

With no options given, the default options for (RefLink[NDSolve, paclet:ref/NDSolve]) and (RefLink[Plot, paclet:ref/Plot]) are used:

odeplot[{y''[x] + y[x] == 0, y[0] == 1, y'[0] == 0}, y[x], {x,0,10}]

This changes the method used by (RefLink[NDSolve, paclet:ref/NDSolve]) and the color in the plot:

odeplot[{y''[x] + y[x] == 0, y[0] == 1, y'[0] == 0}, y[x], {x,0,10}, Method->"ExplicitRungeKutta", PlotStyle->Red]