Placement of Condition /; expressions

It is my practice to place Condition expressions on the left side of := and :> in almost every case.

1. I find this to be more logical as it is part of the pattern

With the exception of use inside Module, Block, or With on the RHS, which is a special case, the Condition depends only on the LHS, and therefore IMHO is more logically placed on the LHS

2. Its behavior remains consistent when used with = and ->

• f[x_] /; x < 5 := 1 and g[x_] /; x < 5 = 1 behave similarly
• f[x_] := 1 /; x < 5 and g[x_] = 1 /; x < 5 behave differently
3. The evaluation path is significantly less complicated

Placing the condition on the RHS requires the internal use of RuleCondition and $ConditionHold which can significantly slow down simple functions. Clear[f, g] f[x_] /; OddQ[x] := 1 f[x_] := 0; g[x_] := 1 /; OddQ[x] g[x_] := 0; f[4] //Trace  {f[4], {OddQ[4], False}, 0}  g[4] //Trace  {g[4],{{OddQ[4],False},RuleCondition[$ConditionHold[\$ConditionHold[1]],False],Fail},0}

a = Range@1*^6;

Timing[f /@ a;]
Timing[g /@ a;]

{0.421, Null}
{0.655, Null}


Nevertheless, the documentation for Condition shows the RHS form and many experienced users also seem to favor this form.

Which form should be standard, and why?

A brief edit: The form f[x_ /; x < 5] := 1 is what I use most often as should be clear to those who read my answers on StackOverflow. I omitted this form specifically because I didn't want to spawn a discussion (bad for SE sites) about purely-stylistic differences. I see now that this may have had the opposite effect. Rather I wish to focus this question on the apparently canonical yet IMHO inferior RHS placement and what its merits are.

-
 I also like the condition next to the symbol as one can see them next to each others, makes sense, rather than having the condition on the symbol by too far removed from it. Come to think of it, your question has made think that Mathematica has no style guide document. I think something like this will be useful. I do not if you know, but Ada has an official style guide document for programmers, which is very useful, here is a link to it adaic.org/resources/add_content/docs/95style/html/cover.html I think Mathematica should have one too. – Nasser Jan 23 '12 at 13:04

I prefer the Condition to appear on the left-hand-side and outside the square brackets for several reasons.

Type signature

I often think of the condition as (part of) the analog of the signature in a typed language, so it should go on the left hand side.

Order of operations

I like that the elements of the function definition appear in the order in which I want them to happen:

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

1. Look for f[x_].
2. Check that x > 0.
3. Return Sqrt[x].
4. (Optional) Check any postcondition (see below).

Function contract

When an argument-checking definition of the form

f[else___] := Throw["Error in f."]


appears, a left-hand-side Condition often plays the role of a precondition in the sense of Design By Contract. A Condition can also appear on the right-hand-side and this plays the role of a postcondition:

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


Consistency of appearance

I prefer f[x_] /; x > 0 to the alternative f[x_ /; x > 0] for consistency, because sometimes placing the Condition inside the square brackets is not possible, such as when the Condition depends on multiple arguments:

f[x_, y_] /; x > y := 1/(x - y)


Update: Rationale

I think Brett's preference of putting the Condition as close as possible to the quantity to which it applies is equally good so I want to explain why I ended up with my slightly different preference.

Basically I was writing a sequence of definitions like this, following Brett's guideline:

f[x_ /; c1[x], y_] := this
f[x_, y_ /; c2[y]] := that
f[x_, y_] /; c3[x, y] := other


Note that all of these define f[x, y]. So there are two things I didn't like about that:

1. The key difference between each LHS is the different conditions on x and y, and these are difficult to read quickly here because they all start at different places and are mixed in with f[x_, y_].
2. When a condition needs to change such that it suddenly starts or stops depending on x or y, I need to move it from inside the square brackets to outside or vice versa.

Now compare:

f[x_, y_] /; c1[x] := this
f[x_, y_] /; c2[y] := that
f[x_, y_] /; c3[x, y] := other


Of course, what would make even more sense would be to adhere to Brett's guideline except in special cases like above! Maybe I will try that now ...

-
+1 Since you work at Wolfram Research, do you have any thought about why only the RHS form is shown in the documentation of Condition? – Mr.Wizard Jan 23 '12 at 15:57
@Mr.Wizard In the documentation for Condition, the very first case "patt /; test" is actually the LHS form of Condition. For example patt could be x_ or f[x_]. The other two are the RHS form. – Andrew Moylan Jan 24 '12 at 2:32
Very nice write up. Personally I keep the practice of keeping conditions on a single variable next to it, simply because I like to think of it as a type or interface. So some functions read h[x_List] and others will read h[x_/;x>4]. But of cause there are cases of mixed patterns as you note, which must be moved outside. – jVincent Jun 15 '12 at 0:07

Style is a matter of taste and education. There is not a definite answer, only a personal answer. Having said that, there is another way for the condition that is common in code:

h[x_ /; OddQ[x]] := 1;
h[x_] := 0
h[4] // Trace


My personal preference is your f[] style, since I find that a good compromise between readability and closeness to the actual symbol involved. Imagine a long Module, then you'd have to scroll quite a bit to get/find the condition. The benefit of the RHS method is readability for people.

-
This is actually the form I prefer. – Heike Jan 23 '12 at 12:18
I use this form as well, preferring to keep conditions close to the pattern they apply to, but I was trying to not complicate things in my question. – Mr.Wizard Jan 23 '12 at 12:33
I have updated the question with a small note attempting to focus the topic on the RHS placement. – Mr.Wizard Jan 23 '12 at 12:40

My general preference is to put the condition as close as possible to the quantity to which it applies:

... to a single argument:

f[x_ /; x > 2, y_] := x + y

{f[1, 2], f[3, 2]}

{f[1, 2], 5}


... to a relationship between arguments:

g[x_, y_] /; x > y := x + y

{g[1, 2], g[3, 2]}

{g[1, 2], 5}


... to a value calculated during the evaluation of the function:

h[x_, y_] := Module[{z = x + y}, z^2 /; z > 3]

{h[1, 2], h[3, 2]}

{h[1, 2], 25}

-
 I think this is a very sensible policy though my answer proposed a different one. – Andrew Moylan Jan 24 '12 at 2:39

My preference is the same as Andrew's, for the consistency and layout reasons he specified. That is, put the precondition Condition after the function's pattern, f[x_, y_] /; test[x,y] := ... - even if test only depends on a single variable/blank.

But I'd like to add an extra reason for not putting the Condition inside the function brackets, which is anytime you can do that, you could use a PatternTest (?) instead. That is, instead of

f[x_/;test[x], y] := ...


you could and maybe should use

f[x_?test, y] := ...


As for putting the condition on the LHS of the rule/definition vs the RHS, I once again agree with Andrew and with Mr.Wizard's comments in the question.

-
I favor x_ /; x<5 over x_?(#<5&) for clarity. If using a named test function I agree that PatternTest will be cleaner. – Mr.Wizard Jan 24 '12 at 12:04