# A problem on the pattern (:) of Heads

I defined

Clear[f, g]
f[(h : Exp | Log)[x_]] := x;
g[(h : Log | Exp)[x_]] := x;


The code gives a weird result:

f[Exp[7]] (* f(E^7) *)
g[Exp[7.7]] (* g(2208.35) *)
f[Log[3]] (* 3 *)
g[Log[3.3]] (* g(1.19392) *)


Only f[Log[3]] is expected. Why?

Exp[7] gets evaluated to Power[E, 7], so it doesn't match the pattern you've defined for f. Exp[7.7] gets evaluated to a finite precision number, so it doesn't match. Log[3] evalutes to Log[3], so it does match one of your patterns. Log[3.3] evalutes to a finite precision number, so it doesn't match.

You can use SetAttributes to give f and g the HoldAll attribute. HoldAll will keep the arguments from being evaluated before the function is evaluated (like wrapping them in Hold).

Also, you don't need to name the head pattern since you don't use that h anywhere.

And just anticipating where this might be going, if you actually want to use the Log[...] or Exp[...] explicitly in your definition, you're going to need a way to keep the argument from being evaluated in the body of the function definition. This is typically done with Unevaluated, which gives you a nice way to inspect an expression without having to account for Hold. Of course, whatever you return will be evaluated immediately, so if that also needs to remain unevaluated, you can wrap the return value with Hold.

Update

Just to make things explicit:

ClearAll[f];
SetAttributes[f, HoldAll];
f[exp : (Exp | Log)[x_]] := ToString[Unevaluated[exp]];
f[Exp[7]]
(* f[Exp[7]] *)


On the other hand:

ClearAll[f];
SetAttributes[f, HoldAll];
f[exp : (Exp | Log)[x_]] := ToString[exp];
f[Exp[7]]


gives

 7
E

• Is it possible not to use Unevaluated? I have tried ^:=, but it didn't work. Oct 23, 2022 at 22:38
• Probably, it depends on exactly what you're trying to do. I was assuming that these were just simplified examples, and if so, then I'd want to see (or have you explain) what the "real" functions look like. Oct 23, 2022 at 22:42
• I added a couple of examples. Oct 23, 2022 at 22:51
• For example, I want the function make all e^x to be in a form of Cos[x]+i*Sin[x]. Oct 23, 2022 at 23:20
• So, we need there to be an I in the exponent, right? Mabye you can just get away with ComplexExpand: ComplexExpand[E^(I x)] gives Cos[x] + I Sin[x]. Oct 23, 2022 at 23:39