f[x__Plus] := Plus @@ (f /@ (List @@ x)) This is also about the same speed as:
f[x__Plus] := Map[f, x] Which is also about the same speed as:
f[x__Plus] := Distribute[Unevaluated[f[x]]] You can test the efficiency of this like so:
var = Sum[a[i], {i, 1, 100000}]; AbsoluteTiming[f[var];] I am reasonably sure there isn't an attribute based solution, and I believe that most of the built-in functions that aren't coded in C rely on pattern matching to manage the distributive property. The trick here is to avoid relying on pattern matching more often than necessary: this splits out every summand in a single replacement.