Maybe this question is so trivial but it has confused me.
I'm studying the What the @#%^&*?! do all those funny signs mean? and in the Rules and patterns
under the Reference for the operator /; there is this example:
In[1]:= f[x_] := ppp[x] /; x > 0
In[2]:= f[5]
Out[2]= ppp[5]
In[3]:= f[-6]
Out[3]= f[-6]
Based on the above example I thought the answer of the following code should be f[-2], as the following:
In[1]:= f[x_] = Sqrt[x] /; x > 0
Out[1]= Sqrt[x] /; x > 0
In[2]:= f[2]
Out[2]= Sqrt[2] /; 2 > 0
In[3]:= f[-2]
Out[3]= f[-2]
I mean the definition f[x_] = Sqrt[x]
should only be used when x>0
. So when I enter -2
as the argument, the definition should not be used and the output will be f[-2]
. But in fact mathematica evaluates the code as follows:
In[1]:= f[x_] = Sqrt[x] /; x > 0
Out[1]= Sqrt[x] /; x > 0
In[2]:= f[2]
Out[2]= Sqrt[2] /; 2 > 0
In[3]:= f[-2]
Out[3]= i Sqrt[2] /; -2 > 0
In spite of the fact that -2<0
, Mathematica uses the definition and produces the answer $i\sqrt{2}$
What's the difference between this code and the first one that makes mathematica use the definition in spite of the negative argument passed to the function?
Update: Response to closure (Michael E2)
There must be something quite subtle going on. It is not just the usual explanation that Set
evaluates the right-hand and SetDelayed
does not, because the right-hand side evaluates to itself (assuming, as Mr. Wizard's answer points out, that x
has no value). This can be seen because the down values are the same in each case:
f1[x_] := Sqrt[x] /; x > 0;
f2[x_] = Sqrt[x] /; x > 0;
DownValues@f1
DownValues@f2
(* {HoldPattern[f1[x_]] :> Sqrt[x] /; x > 0} *)
(* {HoldPattern[f2[x_]] :> Sqrt[x] /; x > 0} *)
Set
instead ofSetDelayed
as well as reasons for putting constraints on patterns. $\endgroup$