Here's a different perspective to complement gwr's answer:
Mathematica has functions for traditional programming, and functions which represent Mathematical concepts and are suitable for symbolic computation. The line between the two is somewhat blurred. This is good for keeping things simple, but it can also be confusing. A stricter CAS would make this distinction explicit at the cost of some convenience, and would provide separate tools for these two types of uses.
"Programming functions" will evaluate immediately, just as they do in other languages. EvenQ
is such a function. Generally, functions ending in Q
will evaluate immediately to either True
or False
. Example:
EvenQ /@ {0, 1, x}
(* {True, False, False} *)
Thus it is better to think of EvenQ[x]
as "x
is of Integer
datatype and is even". It will return False
for anything that is not of the Integer
datatype, which is not the same thing as an integer in the mathematical sense. E.g., EvenQ[2.0]
is False
because 2.0
is Real
. $k\in\mathbb{Z}$ is a mathematical concept, datatypes are a programming concept.
"Mathematical functions" do not evaluate with symbolic values and can be used to represent mathematical statements. Positive
is such a function. Note that even though it returns True
or False
, it does not have Q
in the name. Example:
Positive /@ {0, 1, x}
(* {False, True, Positive[x]} *)
It can be used to represent a Mathematica statement, on which we can perform operations:
FullSimplify[Positive[x^2], Element[x, Reals] && x != 0]
(* True *)
An example of a function that blurs the line between math and programming is If
. If its first argument is neither True
nor False
, then it does not evaluate, and can be used as a sort of substitute for Piecewise
. Note though that it has a fourth argument: when specified, If
will evaluate immediately.
In general, you can think of programming function as "code" that is meant to run. You can think of mathematical functions as data that can be operated on. Probability
is meant to be used with mathematical functions—anything else will evaluate before Probability
even has a chance to see it. That excludes anything that has a Q
in the name.
A note about Defer
: this is a function that is meant purely for displaying/formatting things in notebooks. It is not meant for evaluation control.
EvenQ
works. From the documentation onEvenQ
:EvenQ[expr]
returnsFalse
unlessexpr
is manifestly an even integer (i.e. has head Integer, and is even). Without theDefer
it immediately returnsFalse
inside theProbability
function. $\endgroup$EvenQ
,IntegerQ
, etc.) is what you need to watch out for. In those cases you'd need to useDefer
. $\endgroup$EvenQ
andEqual
(inMod[x,2]==0
) would work differently. But that doesn't explain what the documentation forProbability
says: "For a dataset data, the probability of pred is given bySum[Boole[pred],{x,data}]/Length[data]
"; that code gives the right answer so it must only be 'notionally given by' it. $\endgroup$Trace
is enlightening. For theProbability
version, the first thing that happens is thatEvenQ[x]
is evaluated and, per Jim's observation givesFalse
, whereas, for theSum
version,EvenQ
is only evaluated afterx
is replaced with an integer. $\endgroup$