The first two accomplish the very same thing, for as long as you keep them in this form.
The third one won't always behave the same way though. Consider
fun[x_] := x^2
f3[a_[b_]] := a[b]*a[2 b]
Then f3[fun[z]]
will evaluate to f3[z^2]
because fun[z]
evaluates first. However, if you set SetAttributes[f3, HoldAll]
, then it will behave more similarly to f1
and f2
:
f3[fun[z]]
will now first evaluate to fun[z]*fun[2 z]
, then to 4 z^4
.
This is not the complete story, but giving full details is not always educational. So instead I'll leave you with this reference, which (I think) discusses all the relevant issues:
In particular, look at the section on Nonstandard Evaluation and the Hold...
attributes.