Those two definition are very similar, but the evaluation path is different, and there are cases when the outputs are different. One situation I have thought is when the function has the attribute HoldAll
. The pattern x_Integer
will not make any evaluation of x
before deciding whether it has the head Integer
, while the pattern x_?Integer
Q will evaluate IntegerQ[x]
, which can lead to a different answer:
Attributes[f] = {HoldAll};
Attributes[g] = {HoldAll};
f[x_Integer] := "whatever";
g[x_?IntegerQ] := "something";
f[1 - 1]
g[1 - 1]
or, with UpValues
:
a /: IntegerQ[a] = True;
f[a]
g[a]