# Passing down arguments

In R, one can use ... to pass arguments down to another function. For example

fun <- function(arg1, ...){
print(arg1)
subfun(...)
}

subfun <- function(mex){
print(mex)
}

fun(1, "passed down")


Is there a similar construct in Mathematica? In particular I would like to pass down the attribute WorkingPrecision.

-

Are you looking for implementing option handling by any chance?

Here's a small demonstration of implementing the WorkingPrecision option for function fun, giving it a default value, and always passing it down to subfun.

Options[fun] = {WorkingPrecision -> MachinePrecision}

(* ==> {WorkingPrecision -> MachinePrecision} *)

fun[arg1_, OptionsPattern[]] :=
subfun[arg1, WorkingPrecision -> OptionValue[WorkingPrecision]]

fun[1]

(* ==> subfun[1, WorkingPrecision -> MachinePrecision] *)

fun[1, WorkingPrecision -> 10]

(* ==> subfun[1, WorkingPrecision -> 10] *)


If you need to pass down every option, then @Mr.Wizard's solution is the right one. To restrict it to options only (expressions of the form name -> value), use

ClearAll[fun]
fun[arg_, opt: OptionsPattern[]] := subfun[arg, opt]

fun[1, WorkingPrecision -> 10, someOptions -> "value"]

(* ==> subfun[1, WorkingPrecision -> 10, someOptions -> "value"] *)

-
+1 for doing what I was too lazy to (until the OP clarifies the question). –  Mr.Wizard Feb 17 '12 at 9:40

Here is what I see written, translated as literally as possible:

fun[arg1_, args___] := (
Print[arg1];
subfun[args]
)

subfun[mex_] := (
Print[mex]
)

fun[1, "passed down"]


1

passed down

-
Beat me to it by a minute, pretty much posting the identical answer! imgur.com/qpy9k –  David Feb 17 '12 at 8:02

Both the previous examples are perfect if you know explicitly what option you want to pass.

In the more general case you may want to give none, one, or several of a compound set of options to more than one function chosen from a predefined set of functions.

You may even want to give a function as an argument , or option, to a function which can then utilise options given in the primary function call.

Hopefully the example below shows how to do this for built in and user defined functions, it makes use of OptionValue to access option values and FilterRules to ensure that only valid options are passed to any function.

Clear[f, ff, fff];

(* ff, a function to do something, with a parameter *)
Options[ff] = {Squared -> False};
ff[x_, OptionsPattern[]] := If[OptionValue@Squared, x x, x];

(* fff, another function to do something, with a different parameter *)
Options[fff] = {Cubed -> False};
fff[x_, OptionsPattern[]] := If[OptionValue@Cubed, x x x, x];

(* A set of functions you would like your function to be able to handle options for *)
myFuncs = {ff, fff, Plot};

(* Gather together the options from the set of functions you want your function to support,
plus the options for your own function itself  *)
Options[f] =
Flatten[{Flatten[Options /@ myFuncs, 1], myOpt1 -> 7,
aFunction -> ff}, 1];

(* f,  a function which has it's own options and can accept an arbitrary function
and associated options from the set of those functions who's options it
supports and returns some elements based on those options *)
f[p1_, func_, opts : OptionsPattern[]] := Module[{p, q, r},

(* Utilise the function's own, explicitly defined option, myOpt1 and calls a function,
which was passed as a parameter, along with it's valid options.
This is achieved using FilterRules  *)
p = OptionValue[myOpt1] func[p1, FilterRules[{opts}, Options[func]]];

(* Call a function, passed as an option and any associted options it may
have which were passed into this function *)
q = OptionValue[aFunction][p1,
FilterRules[{opts}, Options[OptionValue[aFunction]]]];

(* Call Plot and filter any options given to this function which are supported by plot *)
r = Plot[
ff[x, FilterRules[{opts}, Options[OptionValue[aFunction]]]], {x,
0, 10}, Evaluate@FilterRules[{opts}, Options[Plot]]] ;

(* return the computed elements *)
{p, q, r}
]
(* An example function call, with options for ff, fff and Plot  *)

f[5, fff, Frame -> True, Squared -> True, Cubed -> True]

-
@Mr.Wizard I can't disagree, but I went with the spirit of the posts above, with a light style of commentary. But I thought it perhaps added a greater depth to the solution. –  image_doctor Mar 28 '12 at 17:57
Thanks for the code comments. +1 –  Mr.Wizard Mar 29 '12 at 7:22
This is VERY helpful! –  Chen Stats Yu Dec 12 '14 at 16:47
Thank you @ChenStatsYu –  image_doctor Dec 31 '14 at 16:34