# Question about Rules and Pattern (The operator patt/;test)

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} *)

• Related: (8829) – Mr.Wizard Sep 19 '15 at 18:53
• I disagree with the close votes. This is a subtle error not explained at all in the documentation, AFAICS. There are valid reasons for using Set instead of SetDelayed as well as reasons for putting constraints on patterns. – Michael E2 Oct 21 '15 at 11:30
• @Mr.Wizard not just related, but already covered and answered there, I think. – LLlAMnYP Oct 21 '15 at 11:52

When using Set rather than SetDelayed you will need to hang the Condition on the left-hand-side:

ClearAll[f]

f[x_] /; x > 0 = Sqrt[x]
f[2]
f[-2]

Sqrt[x]

Sqrt[2]

f[-2]


There are other reasons to prefer this placement; see:

However be aware that the use of Set results in "pre-evaluation" of the RHS which often is not desirable. For example suppose the global Symbol x has a value before the definition is made:

ClearAll[f]
x = 7;

f[x_] /; x > 0 = Sqrt[x]
f[2]
f[-2]

Sqrt[7]

Sqrt[7]

f[-2]


This is probably not what you want. Using := works:

ClearAll[f]

x = 7;

f[x_] /; x > 0 := Sqrt[x]
f[2]
f[-2]

Sqrt[2]

f[-2]