# How to make a function that yields a number under power operator by using pattern matching?

Can I ask you a question related to function and pattern?

I would like to make the function below work which doesn't yield return values I expect. How can it be done?

f[x_]:=x/.t^2_->t;


The value I expect from the above function is like the example below.

f[3^2]
3


Thank you guys. Have a nice day.

## 2 Answers

If you are only ever going to call it as f[a^b] (that is, f[Power[a,b]]), you want to look at the attribute HoldFirst (or HoldAll or similar). Specifically:

SetAttributes[f, HoldFirst];
f[a_^2] := a


Alternatively,

SetAttributes[f, HoldFirst];
f[x_] := Unevaluated[x] /. {a_^2 :> a}


I'm always wary of using Unevaluated, though.

Edited to add: additionally, it looks like you might be confused about the _ syntax. x_f is a shorthand for Pattern[x, Blank[f]]. It doesn't make sense to have 2_ - that is, Pattern[2, Blank[]] - because 2 can't vary. Therefore Mathematica interprets it instead as Times[2, Blank[]] (that is, 2 _).

• Why are you wary of Unevaluated? Jul 15, 2015 at 14:56
• @Mr.Wizard: because it works so locally, and protects things only once. For instance, Identity@Unevaluated[{1}] is {1}. In any large-ish context where I need x to remain unevaluated, I'm (personally) quite liable to write a function where I forget to make sure x is still Unevaluated all the way through - effectively accidentally applying Identity to it at some point - and it takes me ages to track down the bug. I much prefer to work in a way that lets me Inactivate things instead, if I need to do that kind of thing. Jul 15, 2015 at 15:03
• I guess it's a matter of perspective. I think of Unevaluated as momentarily setting a HoldFirst (or whatever position) on the Head surrounding it. Then it is not surprising that this effect does not persist. But as always there is room for different styles and people may go about selecting the right tool for the job in different ways. Jul 15, 2015 at 15:09
• Thank you for the answer so much, Patrick and Mr.Wizard. Dec 17, 2015 at 13:43

One way to do this:

Attributes[f] = {HoldAll};
f[x_] := ReleaseHold[Hold[x] /. {Power[a_, b_] :> a}];


Then:

f[3^2]


gives 3.

And:

f[10000000000000000000000000000000000000000000^1000000000000000]


gives 10000000000000000000000000000000000000000000

And:

f[10^10^10]


gives 10

And:

f[(10^10)^10]


gives 10000000000 (10^10).

• Thank you for the teaching. It was really helpful. I wish you a merry christmas. :) Dec 17, 2015 at 13:44