Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am trying to reproduce the API of a function (written in R) that accepts an arbitrary number of arguments and handles it the same way as it would handle a single argument that is a list of different data sets.

Is there a Mathematica idiom that allows a function to be defined so that:

f[ arg1, arg2, ..., argN ]

behaves the same as

f[ {arg1, arg2, ..., argN} ]

?

share|improve this question
18  
You could just write f[args___]:= f[{args}] and then provide the definition for f[{arg1_, arg2_,...}]. –  Andy Ross Dec 5 '12 at 3:54
add comment

2 Answers

up vote 13 down vote accepted

As described by Andy Ross in a comment, you can make a definition that preprocesses the argument(s) into a canonical form. Turning his example around simply to illustrate flexibility:

f[{args__}] := f[args]

f[args__] := Multinomial[args] / Plus[args]

f[{12, 7, 3}] == f[12, 7, 3]

True

This method is useful for more complicated preprocessing, but in simple cases such as this it is often easier to use Alternatives:

g[{args__} | args__] := Multinomial[args]/Plus[args]

g[{12, 7, 3}] == g[12, 7, 3]

True

Be aware that when using Alternatives you must manually order the patterns, for they are tried in sequence. The pattern args__ | {args__} would not work as desired because args__ will match {12, 7, 3} as a single argument.

share|improve this answer
add comment

There are many ways to handle this. The approach I would most likely take can be illustrated by the following example:

f[seqn : ___] := Module[{args = {seqn}},
    Switch[args,
       {{___}}, "List of args",
       {_}, "One arg",
       {_, __}, "Two or more args",
       {}, "No args"
    ]]

f[{x, y, z}]

(* ==> "List of args" *)

f[{x}]

(* ==> "List of args" *)

f[]

(* ==> "No args" *)

f[x]

(* ==> "One arg" *)

f[x, y, z]

(* ==> "Two or more args" *)

Of course, each application of this technique would replace the strings seen here with some action appropriate to its own needs.

Another approach is to write separate functions for each argument pattern you want to handle:

g[args : {___}] := "List of args"
g[] := "No args"
g[arg_] := "One arg"
g[arg_, rest__] := "Two or more args"

g[{x, y, z}]

(* ==> "List of args" *)

g[{x}]

(* ==> "List of args" *)

g[]

(* ==> "No args" *)

g[x]

(* ==> "One arg" *)

g[x, y, z]

(* ==> "Two or more args" *)
share|improve this answer
5  
What is your reasoning for "most likely" using Switch over multiple definitions? Switch is usually slower and should not be used without cause, IMHO. –  Mr.Wizard Dec 5 '12 at 6:46
1  
@Mr.Wizard. Using Switch appeals to my sense of programming aesthetics because it organizes all the alternatives so they can be dealt with in a single function. I'm usually not all that concerned about execution speed -- not until slow execution becomes really evident. –  m_goldberg Dec 5 '12 at 14:07
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.