Suppose I have the function f
with the following definition assigned to it:
f // ClearAll;
f // Attributes = { HoldAll };
f /: HoldPattern[ f[x_] + f[y_] ] := upvalue;
If I evaluate f[x] + f[y]
, I get upvalue
as expected. Now if I instead use the definitions:
f // ClearAll;
f // Attributes = { HoldAll };
f /: HoldPattern[ f[x_] + f[y_] ] := upvalue;
f[x_] := downvalue;
the last one will take precedence, so f[x] + f[y]
gives 2 downvalue
. From a trace, it's pretty easy to see why this happens, since the second argument isn't seen until after the first has been evaluated:
(* In *)
Column[ Trace[ f[x] + f[y], TraceOriginal -> True ] ]
(* Out *)
f[x] + f[y]
{Plus}
{f[x], {f}, f[x], downvalue}
{f[y], {f}, f[y], downvalue}
downvalue + downvalue
2 downvalue
{Times}
{2}
{downvalue}
2 downvalue
However, I'd like to know if there's good way to prioritize the first definition so I get upvalue
instead? A possible workaround would be to do something like this:
(* In *)
Hold[ f[x] + f[y] ] /. UpValues[f] /. DownValues[f] // ReleaseHold
(* Out *)
upvalue
but that's a pretty ugly solution. Anyone have any better ideas?