# An argument pattern that my function can treat as Times[constant, variable]

I want to define a function of two variables, func[f_, g_], such that when it sees a general constant multiplying one of the variables, say a, it will take it outside the evaluated expression. So for example, if f and g are variables and a is a constant multiplying g, it will be evaluated as

func[f_, a_ g_]:= a func[f_, g_]


I need to inform Mathematica that a is a constant, not a variable, and that it should be pulled out of the expression.

• m_goldberg, I know your edit was intended to be helpful, and the vast majority of your edits are, but I think it has been discussed that fixing syntax such as func(a, b) = . . . is a bad idea because the that is often a problem that needs to be addressed in the answers rather than "swept under the rug" as it were. Jul 31, 2014 at 1:28

I think you need a clear differentiation of "constant" and "variable" and I don't see that in your question. For the sake of the example let us consider anything numeric to be a constant and anything else to be a variable, so my PatternTest function will be NumericQ.

func[f_, a_?NumericQ g_] := a func[f, g]


Now:

func[foo, 6 bar]

func[x, Pi y^2]

6 func[foo, bar]

π func[x, y^2]

• ok, but with this solution I want to insert a customized constant, say "a", and have the function pull it out. i.e. func[foo, a bar] will yield a func[foo, bar]
– Gogo
Jul 31, 2014 at 21:41
• @Gogo Do you have a list of expressions that you wish to consider constant? Only literal a? Something else? Jul 31, 2014 at 22:27
• Yes, I have a specific parameter. I want a factor "1/M" to be such a constant
– Gogo
Aug 1, 2014 at 13:58

Assuming g is the only variable in the second position and any thing before is a constant:

ClearAttributes[Times, Orderless];
func[f_, a__ g_] := a func[f, g]

func[f, 3 g]
func[f, 3 Pi g]
func[f, 3 Pi a^3 g]
(*3 func[f, g]*)
(*3 \[Pi] func[f, g]*)
(*3 \[Pi] a^3 func[f, g]*)


The following is a variation of Mr. Wizard's answer...

ClearAll[isConstantQ, func];
isConstantQ[v_] = False;
isConstantQ[1/M] = True;
SetAttributes[func, HoldRest];

func[f_, g : Times[a_, b_] /; isConstantQ[a]] := Times[a, func[f, b]];

func[f_, g_] := NormalFunc[f, g];

DownValues[func]
func[aa, 1/M bb]
func[aa, ZZ bb]


Results in

{HoldPattern[func[f_, g : a_ b_ /; isConstantQ[a]]] :> a func[f, b],
HoldPattern[func[f_, g_]] :> NormalFunc[f, g]}
NormalFunc[aa, bb]/M
NormalFunc[aa, bb ZZ]