Named patterns in Except
It seems that f[Except[0, a_], Except[0, a_]]
isn't considered doubled argument while this
f[a : Except[0], a : Except[0]]
is. So the former isn't considered special case and is overwritten by your next definition.
I can't explain properly but seems to be expected.
ClearAll[f];
f[a_, a_] := 0 (*or f[a : Except[0], a : Except[0]] if f[0,0] should give f[0,0]*)
f[a : Except[0], b : Except[0]] := {a, b}
f[1, 2]
f[0, 1]
f[0, 0]
f[1, 1]
{1,2} f[0,1] 0 0
Another way to get two definitions is to only use Except
on the first argument for the case where the arguments are identical.
Clear[f]
f[Except[0, a_], a_] := 0
f[Except[0, a_], Except[0, b_]] := (a - b) Log[a - b]
Annoyingly it doesn't matter the order for the definitions it comes out like this:
DownValues@f
(* {HoldPattern[f[Except[0, a_], Except[0, b_]]] :> (a - b) Log[a - b],
HoldPattern[f[Except[0, a_], a_]] :> 0} *)
So in order to get the right behaviour you have to do
DownValues[f] = Reverse@DownValues@f
(* {HoldPattern[f[Except[0, a_], a_]] :> 0,
HoldPattern[f[Except[0, a_], Except[0, b_]]] :> (a - b) Log[a - b]} *)
Now
f[3, 1]
f[3,0]
f[2,2]
f[0,0]
gives
2 Log[2]
f[3,0]
0
f[0,0]