# Apply UpValues before Listability

I'm trying to modify Plus but am running into trouble with it being Listable:

ClearAll[f, g, h]
Attributes[f] = {Listable};
h /: f[x_h, l_List] := 0
h /: g[x_h, l_List] := 0
f[h[1], {1, 1}]   (* {f[h[1], 1], f[h[1], 1]}, not OK I want 0 *)
g[h[1], {1,1}]    (* 0 as expected *)


How can I make the UpValue (or equivalent) have higher priority than the listability?

EDIT: I ended up wanting to do this again and figured I'd fix the Plus properly. Here it is working using Sashas answer and Mr.Wizards $Pre method: $Pre =.
ClearAll[myPlus]; Attributes[myPlus] = {Orderless};
Unprotect[InterpolatingFunction]; UpValues[InterpolatingFunction] = {};
InterpolatingFunction /:
myPlus[y_InterpolatingFunction[t_Symbol], l_List] :=
Interpolation[
MapThread[List, {y["Grid"], l + # & /@ y["ValuesOnGrid"]}],
InterpolationOrder -> First[y["InterpolationOrder"]]][t]
myPlus[other__] := +other
$Pre = Function[x, Unevaluated@x /. Plus -> myPlus, HoldAllComplete]; Protect[InterpolatingFunction]; y = Interpolation[Table[{i, RandomReal[{0, 1}, 2]}, {i, 1, 10}]]; ParametricPlot[{y[t], y[t] - {1, 1}}, {t, 1, 10}]  • You can't do that, or I'll be very surprised. Change your design somehow. It's hard to help in that without knowing a little bit about the bigger picture. Perhaps for your case adding the "listability" as e:f[_, l_List]:=Thread@Unevaluated@e or something similar, but that depends on the case at hand – Rojo Feb 5 '13 at 13:55 • Oh, f is Plus, my bad. – Rojo Feb 5 '13 at 13:57 • Yes, I agree. Not possible (I even tried with $Pre and $Post to fool the evaluator, but you cannot do that). Just program Listable like f[x_, l_List] := Thread[f, {x, l}]; and all is good. – Rolf Mertig Feb 5 '13 at 14:01 • @Rojo Updated with bigger picture – ssch Feb 5 '13 at 15:37 • I think this is one of these things which are really hard to make different generally and consistently, since one would have to explicitly go against the standard evaluation sequence. I would reconsider the design of whatever you try to achieve with this. While I will be the first to suggest workarounds which change system's behavior in many cases, I also think that admitting and accepting certain limitations of the system can sometimes be more productive. – Leonid Shifrin Feb 5 '13 at 20:48 ## 2 Answers This seems disgusting, but here it goes h /: Plus[x_h, l_List] := withPlusListability[True][ blabla; 0 ] withPlusListability[bool_: True | False] := Function[code, InternalInheritedBlock[{Plus}, Unprotect[Plus]; If[bool, SetAttributes, ClearAttributes][Plus, Listable]; code ], HoldFirst]; withH = withPlusListability[False];  So withH[ Print[h[3] + {4, 5}]; Print[h[3] + 7]; ];  prints (* 0 7+h[3] *)  While you evaluate code iniside withPlusListability[True|False], it takes care that Plus has|doesn't have the Listable attribute, without changing it globally. h's definition will only have a chance of matching with an unlistable Plus. Plus is one of those symbols that are so special you really try not to mess with. As @Mr.Wizard warned, this will likely break for packed arrays, because it probably has been optimized to cut some corners. • @MrWizard, surprisingly, h[3] + RandomReal[{-1, 1}, 10]; works. Could you try it in v7? – Rojo Feb 5 '13 at 14:31 • Cool, didn't know about InternalInheritedBlock – ssch Feb 5 '13 at 15:56 • Rojo: yes, it works. I need to take a closer look at this. – Mr.Wizard Feb 6 '13 at 1:28 Contrary to Rolf Mertig's comment I believe $Pre does work.

h /: myPlus[_h, _List] := 0
myPlus[other__] := +other


Then set $Pre: $Pre = Function[x, Unevaluated@x /. Plus -> myPlus, HoldAllComplete];


Test:

h[1] + {4, 5, 6}

0

z[1] + {4, 5, 6}

{4 + z[1], 5 + z[1], 6 + z[1]}

• @RolfMertig is pessimistic (comments) these days – Rojo Feb 5 '13 at 14:36
• +other!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! HAAAAAAAAAAA +1 – Rojo Feb 5 '13 at 14:39
• You make it look so easy, thanks! – ssch Feb 5 '13 at 15:59
• @Rojo I'm afraid I don't understand your outburst. Unintentional humor? Does "plus other" mean something in contemporary parlance? – Mr.Wizard Feb 5 '13 at 16:36
• @ssch Glad I could help. :-) – Mr.Wizard Feb 5 '13 at 16:37