# 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) Commented Sep 19, 2015 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. Commented Oct 21, 2015 at 11:30
• @Mr.Wizard not just related, but already covered and answered there, I think. Commented Oct 21, 2015 at 11:52

## 1 Answer

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]