# Prevent evaluation of parameter inside function

I am learning mathematica, and I am stuck at the point where I want to pass an unevaluated expression (a polynomial) to a function and work with that expression / polynomial inside the function. For simplification reason, assume the following setup, which should give me the coefficients of the polynomial:

SetAttributes[myCoef, HoldAll]
myCoef[exp_] := CoefficientList[exp, Variables[exp]]


This works fine for the following call:

p = myCoef[5*x^3 + 4*x^2 + 3]
(* Returns {3, 0, 4, 5} *)


The problem is, when I set x on the global scope:

x = 5
p = myCoef[5*x^3 + 4*x^2 + 3]
(* Returns 728 *)


How can I prevent the evaluation of 5*x^3 + 4*x^2 + 3 to 728? What would I have to change in myCoef to make it work, even if x is defined globally?

• You could use \[FormalX] (and similar) or maybe use pure functions as in myCoef[5*#^3 + 4*#^2 + 3]. – b.gates.you.know.what May 25 '17 at 14:56
• SetAttributes[newPoly, HoldAll] should probably have myCoef rather than newPoly? – jjc385 May 25 '17 at 17:24
• Oh yes, that was just a typo when I wrote the example, for sure it is myCoef, I edit it. – Markus Weninger May 25 '17 at 18:24
• Weird. For me it returns {0,1} which I just glossed over as being the right answer, but obviously it's a) wrong, b) in the correct form for an answer from CoefficientList. Obviously my suggestion wasn't correct, but I'm curious why it's giving two different answers. What version are you using? – N.J.Evans May 25 '17 at 18:38
• @N.J.Evans OK, I'm now getting the same output as you -- {0,1}. Somehow I'd replaced HoldForm with something that looked the same but contained non-printing characters -- its FullForm was HoldFor\:200c\:200bm. Weird, but explains why what looked like HoldForm showed up in blue rather than black. – jjc385 May 25 '17 at 22:58

Of course, the simplest solution is to make sure you haven't defined the variables you're using in your polynomials, but there are other ways to go.

You could wrap the code in Module or Block :

Block[{x},
myCoef[5*x^3 + 4*x^2 + 3]
]

{3, 0, 4, 5}


If you wanted to, you could build this into myCoef by adding a second argument :

myCoef[exp_, varsToBlock_List] :=
Block[varsToBlock,
CoefficientList[exp, Variables[exp]]
]

x=2;
myCoef[5*x^3 + 4*x^2 + 3, {x}]

{3, 0, 4, 5}


Note that the original form of myCoef still works for a variable that doesn't have a definition:

myCoef[5*y^3 + 4*y^2 + 3]

{3, 0, 4, 5}


Of course, it would be nice to solve the problem without having to explicitly specify the variables which need to be held. I'm unsure how to do this, but perhaps someone else will come up with a solution.

• That's a nice solution! I will try this one when I come home, thanks! :) – Markus Weninger May 25 '17 at 18:25
• I appreciate the accept, but I would strongly recommend waiting ~24 hours for others to submit solutions, particularly because I suspect a better solution is possible. – jjc385 May 25 '17 at 18:31