Evaluate a variable inside an If clause?

This function

fn[x_]=Module[{ww},
 ww=ArcTan[x];
 If[x<ww,  ww,(*else*)  x ]
]

evaluates to

If[x < ArcTan[x], ww$375, x]

Why does the second occurrence of the local variable ww remain as a variable name instead of being evaluated like the first occurrence?

You need := in your definition because the = tries to evaluate everything in the assign immediately (which it can’t). You need the delayed assignment.

To be clear: do fn[x_]:= …

If you look at the help page for If and you click on Details then you find

If[condition,t,f] is left unevaluated if condition evaluates to neither True nor False.

Mathematica recognized your If and then evaluated your condition to try to determine whether it was True or False. To do that it evaluated x and the local variable ww, to do that it determined that ww had been assigned the value ArcTan[x]. You have not assigned a value to x and so the value of x<ArcTan[x] is just x<ArcTan[x]. That is neither True nor False and thus it evaluates nothing further and the result is If[x<ArcTan[x], ww, x]

If[condition,t,f] is left unevaluated if condition evaluates to neither True nor False.

I see, that’s the reason. So I need to explicitly tell mathematica to evaluate it, e.g.

fn[x_]=Module[{vv,ww},
 ww=ArcTan[x];
 If[x<ww, Evaluate[ww], Evaluate[ (x+ww)/2 ]
]

which yields the desired result

If[x < ArcTan[x], ArcTan[x], (x + ArcTan[x])/2]

Similarly, with a Which statement I need to sprinkle Evaluate in the right places:

fn[x_]=Module[{ww,yy},
 ww=ArcTan[x];
 yy=Exp[x];
 Which[
  x<0, Evaluate[ww],
  Evaluate[x<ww], Evaluate[yy],
  True, Evaluate[2*yy]
 ]
]

which yields the desired result

Which[x < 0, ArcTan[x], x < ArcTan[x], E^x, True, 2*E^x]

Thank you.

Do I understand it right that you want fn[z] to work even if z is a symbol (and thus the If function will not be evaluated)?

If so, use With:

Clear[fn]
fn[x_] := With[{ww = ArcTan[x]}, If[x < ww, ww, x]]

fn[z]
(* If[z < ArcTan[z], ArcTan[z], z] *)

See here: https://mathematica.stackexchange.com/questions/559/what-are-the-use-cases-for-different-scoping-constructs

One of the uses of With is injecting evaluated values.

Or perhaps what you want is fn to evaluate only with numbers:

Clear[fn]
fn[x_?NumericQ] := With[{ww = ArcTan[x]}, If[x < ww, ww, x]]

Thank you. You are right about wanting it to work with symbols. Using “With” is a good idea. Also I realized that “Piecewise” is appropriate:

fn[x_]=Module[{ww},                                                      
                 ww=ArcTan[x];                                                  
        Piecewise[{{ww,x<ww}},x]                                                
        ] 

evaluates to

Piecewise[{{ArcTan[x], x < ArcTan[x]}}, x]

which does what I wanted.

Yes, Piecewise is more suitable here because it is explicitly designed for symbolic computations. If is primarily for flow control when programming, but it tends to work with many symbolic math functions too.