Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I would like to decide whether an option passed to my custom function has the value Automatic or something else. This is my attempt:

f[x_, OptionsPattern[{DataRange -> Automatic}]]:= 
    Module[{opt = OptionValue[DataRange]},{x, If[opt == Automatic, True, opt]}];

However,

f[x, DataRange -> 20]

produces

{x, If[20 == Automatic, True, opt$540]}

rather than the expected

{x, 20}

What do I need to change?

share|improve this question

2 Answers 2

up vote 10 down vote accepted

You need to use === (or SameQ) instead of == (or Equal) to test the condition. This is because === always returns True or False, whereas == can remain unevaluated. For example:

a === b
(* False *)

a == b
(* a == b *)

The fact that == remains unevaluated is why it is useful in Solve, Reduce and related functions, where you can write an expression such as a x^2 + b x + c == 0.

Now, == does evaluate in cases such as comparisons between numeric quantities and strings or when the objects being compared are identical. For example:

1 == 1
(* True *)

"abc" == "def"
(* False *)

2 == "a"
(* False *)

a == a
(* True *)

However, make note of the fact that comparison between machine numbers and exact numbers can give different results for == and ===:

1 === 1.
(* False *)

1 == 1.
(* True *)

This is because SameQ tests if the two expressions are exactly the same, down to the representation (which they're not), whereas for Equal (see link to docs above):

Approximate numbers with machine precision or higher are considered equal if they differ in at most their last seven binary digits (roughly their last two decimal digits).

share|improve this answer
    
SameQ of two finite-precision numbers also applies a tolerance; it's just less than that applied by Equal. So it isn't strictly correct to say that SameQ returns True if and only if the expressions are identical. (Also, one can override SameQ, but if you use TrueQ here that is no longer an issue, and the difference between Equal and SameQ is then a moot point.) –  Oleksandr R. Jul 28 '12 at 1:13
    
@OleksandrR. Is that not the case only for arbitrary precision numbers? If I recall, it considers them to be identical only if they're not MachinePrecision and differ only in the last bit. –  rm -rf Jul 28 '12 at 1:35
    
@R.M Problem solved! Thanks! –  groovybaby Jul 28 '12 at 5:28
    
As an alternative, one could also do If[opt == Automatic, True, opt, opt] for cases where == does not evaluate –  rm -rf Jul 30 '12 at 14:46
    
@R.M yes, that's right. I would however consider it reasonable to overload SameQ if different concepts of sameness are needed (which could of course give arbitrary results), whereas TrueQ is a binary distinction that cannot readily admit any other meanings. In this case one could equally well use the fourth argument of If, which is perhaps more succinct than adding TrueQ. –  Oleksandr R. Aug 3 '12 at 13:30

Generally speaking the function you need is TrueQ:

TrueQ[expr] yields True if expr is True, and yields False otherwise.

Example:

TrueQ[ x == Automatic ]

False

Alternatively you can use SameQ (===) but this changes the meaning of the comparison from mathematical to structural. Frequently you want to match based on numeric rather than structural equivalence:

If[TrueQ[# == 0], "match", "fail"] & /@
   {0, 0., E^(I Pi/4) - (-1)^(1/4), 1, symbol}

{"match", "match", "match", "fail", "fail"}

share|improve this answer
    
I went with SameQ because the original question was on matching Automatic in options, which is structural. This is a good addition to the general question (which was my rewording). I should've mentioned it when I made it general. Thanks for mentioning TrueQ :) –  rm -rf Aug 2 '12 at 15:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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