Consider the (bad) input
NSolve(1,1,1). This yields an error message, and returns
NSolve(1,1,1). This return value seems to be literally the expression
NSolve(1,1,1) // FullForm is again
NSolve(1,1,1), and it seems usable as an inert expression internally (e.g.
Nsolve(1,1,1) /. 3 sends two error messages, one each time it attempts evaluation, and ultimately returns
I want to make a function that behaves like this, and I’m curious how Mathematica manages to do this without hitting the recursion limit. Consider a function which throws an error if its argument is
0 and otherwise returns
f::err = "Error!";
f(a_) := If(a == 0, Message(f::err); f(a), 1)
f(0) obviously goes into an infinite loop of definition application. The attempts
f(a_) := If(a == 0, Message(f::err); Unevaluated(f(a)), 1)
f(a_) := If(a == 0, Message(f::err); Return(Unevaluated(f(a))), 1)
f(a_) := If(a == 0, Message(f::err); Defer(f(a)), 1)
f(a_) := If(a == 0, Message(f::err); HoldForm(f(a)), 1)
are all inequivalent to whatever Mathematica does (as one can see upon applying
FullForm if necessary).
So what’s Mathematica doing, or what’s an equivalent implementation? (Am I missing something obvious?) Does Mathematica somehow retain a record of whether it has already tried to evaluate a certain expression during a given evaluation process somehow? Or is there a better “don’t evaluate further” head than
Defer out there somewhere?