I'd like to understand how functions like Mean are overloaded to provide the right behavior for the distributions in Mathematica (like NormalDistribution or PoissonDistribution).

I originally assumed it was through the use of UpValues, but now I'm not so sure...

So, if I wanted to implement a function or distribution and define a behavior for it when another function like Mean is applied to it, how would I go about it? I know it's not the following:

f[x_]:=2+x
f /: Mean[f[x_]] := 3 x


Desired behavior:

f
Mean[f]

(*
==> 5
==> 9
*)


Symbolic(!) distributions are recognized by their head, not by their PDF:

Mean[PDF[NormalDistribution[0, 1], x]]


Mean[E^(-(x^2/2))/Sqrt[2 π]]

So instead of messing around with Mean, I would rather suggest

distro /: PDF[distro[μ_, σ_], x_] := E^(-((x - μ)^2/(2 σ^2)))/(Sqrt[2 π] σ);
distro /: Mean[distro[μ_, σ_]] := μ;
distro /: Variance[distro[μ_, σ_]] := σ^2
Mean[distro[0, 1]]
Variance[distro[0, 1]]


0

1

This works:

Unprotect[Mean];
SetAttributes[Mean, HoldFirst];
Protect[Mean];
f[x_] := 2 + x
f /: Mean[f[x_]] := 3 x


Since using Unprotect is not reccomended here's another way.

mean[x_] := Mean[x]
SetAttributes[mean, HoldFirst]
f[x_] := 2 + x
f /: mean[f[x_]] := 3 x

• It should be mentioned that SetAttributes[Mean, HoldFirst] is likely to break many internal functions that depend on Mean – Jason B. Dec 22 '18 at 15:05
• Thanks for this solution - I did learn something from your answer but I was trying to avoid setting DownValues. – hmode Dec 23 '18 at 1:35