13
$\begingroup$

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?

$\endgroup$
0

2 Answers 2

18
$\begingroup$

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).

$\endgroup$
5
  • 2
    $\begingroup$ 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.) $\endgroup$ Commented Jul 28, 2012 at 1:13
  • $\begingroup$ @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. $\endgroup$
    – rm -rf
    Commented Jul 28, 2012 at 1:35
  • $\begingroup$ @R.M Problem solved! Thanks! $\endgroup$
    – groovybaby
    Commented Jul 28, 2012 at 5:28
  • 1
    $\begingroup$ As an alternative, one could also do If[opt == Automatic, True, opt, opt] for cases where == does not evaluate $\endgroup$
    – rm -rf
    Commented Jul 30, 2012 at 14:46
  • $\begingroup$ @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. $\endgroup$ Commented Aug 3, 2012 at 13:30
6
$\begingroup$

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"}

$\endgroup$
1
  • $\begingroup$ 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 :) $\endgroup$
    – rm -rf
    Commented Aug 2, 2012 at 15:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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