# How do I get Mathematica to return a function call unevaluated?

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:

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

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

• A proper predicate does not have the behavior you request, but returns True or False for any expression it is given. Commented May 22, 2014 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?) Commented May 22, 2014 at 13:58
• On OSX and v9 AlgebraicsQ[x_Real] := Element[x, Algebraics] works as you want.
– gpap
Commented May 22, 2014 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. Commented May 22, 2014 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
Commented May 22, 2014 at 14:13

Here's how this can be done:

ClearAll[algebraicQ]
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.

• @Charles - How did you paste the image to SE?
– eldo
Commented May 22, 2014 at 14:58
• Commented May 22, 2014 at 16:41
• Commented May 22, 2014 at 16:47
• @belisarius - Thanks for pointing me to the SE-Uploader. This smart gadget should be mentioned somewhere in the SE-Help.
– eldo
Commented May 22, 2014 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). Commented Jul 5, 2016 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]} *)

• Hah! So at least I wasn't too far off the mark, just careless. Thanks for pointing this out! Commented May 22, 2014 at 17:52