Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How do I get Mathematica to return a function call (conditionally) unevaluated? I expect this may use the slightly-mysterious Hold function.

As a toy example, suppose I want to define AlgebraicQ such that AlgebraicQ[x] returns True or False when Element[x, Algebraics] evaluates to True or False, but otherwise to returns AlgebraicQ[x], just like the other predicate functions do. (I can't just ask if Element[x, Algebraics] == True, because this is itself unevaluated.)

Edit: The first thing that came to mind didn't work, as you can see: With the definition AlgebraicQ(a_) := Element(a, Algebraics), the function AlgebraicQ[Pi+E] returns Element(E+Pi, Algebraics) instead of the desired AlgebraicQ(Pi+E). Parens used in place of brackets because of platform limitations.

I had tried this before posting, but on a recommendation I tried again with a fresh kernel (pictured above) with the same results. I also tried

AlgebraicQ[a_] := True /; Element[x, Algebraics]
AlgebraicQ[a_] := False /; ! Element[x, Algebraics]

based on an earlier suggestion but this seems not to work at all.

Final working solution

based on Szabolcs' answer:

AlgebraicQ[a_] := With[{result = Element[a, Algebraics]},
  result /; MatchQ[result, True | False]]

which tests as expected:

AlgebraicQ /@ {7, Pi, Pi + E}

Out[2]= {True, False, AlgebraicQ[E + Pi]}

share|improve this question
A proper predicate does not have the behavior you request, but returns True or False for any expression it is given. – m_goldberg May 22 '14 at 13:54
@m_goldberg: The built-in AlgebraicIntegerQ has precisely the same behavior I'm describing. (How could a function possibly guarantee to return True or False when the answer is not even known to mathematicians?) – Charles May 22 '14 at 13:58
On OSX and v9 AlgebraicsQ[x_Real] := Element[x, Algebraics] works as you want. – gpap May 22 '14 at 14:07
@gpap: I can't imagine how, honestly. I mean, clearly that should work if I gave it a non-Real, but for a Real it should return Element[x, Algebraics] because that's what you're telling it to return. Very strange, I'd be interested to learn more about this case. – Charles May 22 '14 at 14:10
Sorry, when I say "as you want" I mean the example you referred to (these are evaluated on a fresh kernel). – gpap May 22 '14 at 14:13
up vote 15 down vote accepted

Here's how this can be done:

algebraicQ[x_] := Module[{result},
  result = Element[x, Algebraics]; 
  result /; MatchQ[result, True | False]]

The key to these types of problems is usually a special use of Condition inside Block/Module/With which allows sharing localized variables between the condition and the body of Module.

At this point I should note that the convention seems to be that any function that ends in ...Q will always return either True or False. Consider EvenQ vs Positive. EvenQ[x], with x undefined, gives False. Positive[x] stays unevaluated. I know of only a very few edge cases which don't follow this. Naming this algebraicQ would violate that convention.

share|improve this answer
@Charles - How did you paste the image to SE? – eldo May 22 '14 at 14:58
@belisarius - Thanks for pointing me to the SE-Uploader. This smart gadget should be mentioned somewhere in the SE-Help. – eldo May 22 '14 at 17:50
@Agreeing with the convention! I strongly hope that WRI sticks to this, minimizing headaches to sort out non-binary cases (True/False/unevaluated). – István Zachar Jul 5 at 12:27

Your earlier approach would have worked if you had actually tested the argument to the function (a) rather than the undefined symbol x...

AlgebraicQ[a_] := True /; Element[a, Algebraics]
AlgebraicQ[a_] := False /; ! Element[a, Algebraics]
AlgebraicQ /@ {7, Pi, Pi + E}

(* {True, False, AlgebraicQ[E + Pi]} *)
share|improve this answer
Hah! So at least I wasn't too far off the mark, just careless. Thanks for pointing this out! – Charles May 22 '14 at 17:52

Your Answer


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.