2
$\begingroup$

Suppose one defines a generic function

f[a_, b_, c_]:= a + b*c

Is there a built in function that allows to get the dependent variables? Like:

Variables[f[x, y, z]] = {x, y, z}

Thanks!

$\endgroup$
5
  • $\begingroup$ should be a+b*c $\endgroup$
    – cvgmt
    Commented Nov 11 at 13:39
  • 1
    $\begingroup$ You can write a function to do that, but you need to clarify how you want it to behave. What x has been defined as 7? Do you want Vars[f[x,y] to return {x,y} or {7,y}? How should it work with Vars[f[g[z],y]? {g[z],y} or {z,y}? Etc. $\endgroup$
    – lericr
    Commented Nov 11 at 14:09
  • 1
    $\begingroup$ There already is a built-in function called Variables that does exactly that. Is that not what you need? $\endgroup$ Commented Nov 11 at 14:16
  • $\begingroup$ Thanks for the remarks and sorry if I haven't been clear enough. Variable was not was I was looking for, because the output is dependent on how one defines the function. $\endgroup$
    – nicarepo
    Commented Nov 11 at 14:24
  • 1
    $\begingroup$ This is easily found in the documentation. $\endgroup$ Commented Nov 11 at 17:34

2 Answers 2

7
$\begingroup$

The simplest version of this would probably be something like this:

SetAttributes[Arguments, HoldAll];
Arguments[_[args___]] := HoldForm[{args}]

I used Arguments because Variables is a built in system symbol (although, if you know exactly what kind of functions you'll use with this, you might find that Variables actually works for you). To demonstrate,

x = 7;
Arguments[f[x, y, z]]
(* {x, y, z} *)

Even though this looks like a simple list, if you look at the FullForm of the result, it's this:

HoldForm[List[x, y, z]]

I don't know if that's what you want. I don't know exactly where you want to interrupt evaluation. There are many other versions depending on exactly what you want. For example, if you just want to avoid applying fs definition but you want to allow the arguments to evaluate, then just remove the HoldForm.

$\endgroup$
3
  • $\begingroup$ This exactly what I was looking for, thanks! So, the first underscore in the definition of "Arguments" means that you can give a generic input? Or it is the same as writing f_[args___]? $\endgroup$
    – nicarepo
    Commented Nov 11 at 14:31
  • 3
    $\begingroup$ It's effectively the same as f_[args___], but since we don't need to reference the head, we don't need to give that pattern a name. $\endgroup$
    – lericr
    Commented Nov 11 at 14:33
  • $\begingroup$ Got it, thanks again! $\endgroup$
    – nicarepo
    Commented Nov 11 at 14:37
3
$\begingroup$

This is a straightforward way:

List @@ Unevaluated[f[x, y, z]]

Or for more complicated calls:

List @@ Unevaluated[f[r s, t, u]] // Variables

Or for really complicated calls:

Integrate`getAllVariables[List @@ Unevaluated[f[r Exp[s], t, u]], {}]

Probably this would work if f[..] returns a mathematical formula (see Get all variables in an expression with Variables[])):

Integrate`getAllVariables[f[x, y, z]], {}]

But if f[] takes a long time to evaluate, the Unevaluated[] version will be better.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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