Consider the following expressions:

f[x_Integer] := x, 
f[x_] := x /; x ∈ Integers, 
f[x_?IntegerQ] := x

All of the expressions above (and probably others which I don't know) seem to do the exact same thing.

However, what I'm curious to know is: are they really equivalent, or are there circumstances where one is preferable (faster, slower?) over the other?

  • $\begingroup$ Do a Trace on each, s/b/ illuminating... $\endgroup$
    – ciao
    May 18 '15 at 21:08
  • 2
    $\begingroup$ closely related: 1835 $\endgroup$
    – Kuba
    May 18 '15 at 21:09
  • 2
    $\begingroup$ I would be surprised if [x_Integer] := x were not the fastest of the examples you give, for the simple reason that it requires the least effort to determine whether the actual argument passed matches the argument pattern. $\endgroup$
    – m_goldberg
    May 18 '15 at 22:39

In version 10.1 timings are pretty much as I expected:

f1[x_Integer] := x;
f2[x_] := x /; x ∈ Integers;
f3[x_?IntegerQ] := x;

First @ Timing @ Do[#[i], {i, 1*^6}] & /@ {f1, f2, f3}
{0.374402, 1.06081, 0.499203}

As m_goldberg commented _Integer should be fastest as unlike the others it does not require evaluation; it directly matches the ("implicit") head of the argument. This difference becomes more important with functions that hold their arguments.

SetAttributes[{f1, f2, f3}, HoldAll]

foo := Print["pop!"]

With f1 the Print does not evaluate:

f1[foo];  (* nothing printed *)

With f2 and f2 it does:




That also results in this evaluation behavior:

z = 1;




f1 matches only an explicit integer and z is not but since f2 and f3 evaluate their arguments in the course of pattern matching the assigned value of z is used, matched, and returned.

  • $\begingroup$ I like the way you explain things. If one wants to understand MMA deeply then he just need to follow your answers:). $\endgroup$ May 19 '15 at 5:17
  • $\begingroup$ @Algohi Thanks! Several people have suggested I write a book on Mathematica. Recently I am beginning to consider that seriously. Feedback on what is clear or useful in my answers and what is confusing, needless, or simply wrong is appreciated. $\endgroup$
    – Mr.Wizard
    May 19 '15 at 5:28
  • $\begingroup$ That would be great help from you to the community. I strongly support the idea you write a book and I will be waiting to read it. $\endgroup$ May 19 '15 at 5:31
f1[x_Integer] = x;
f2[x_] = x /; x \[Element] Integers; 
f3[x_?IntegerQ] = x;

Timing[f1 /@ Range[10^6];]

{0.424561, Null}

Timing[f2 /@ Range[10^6];]

{0.69525, Null}

Timing[f3 /@ Range[10^6];]

{0.630597, Null}


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.