# Background

Suppose I have begun a fresh kernel session, and I have defined the following function alone:

F[x_, y_] := x + y;


One expected use of F is this:

F[0, 1]


Consider three examples of unexpected uses. One with the wrong name, one with an incorrect number of arguments, and a final one with an expected application of + to an unexpected application of F and 1.

G[0, 1]
F[0]
F[0] + 1


All of these are valid Mathematica expressions, however I am not interested in them in this context.

# Question

How can I ensure that an expressions contains no unevaluated function applications?

1. Is there a function which takes an expression and asserts this requirement?
2. Is there a function which asserts this over all following expressions in the context?
• – WReach Jan 24 at 19:23
• @WReach Thanks. That's an informative post. – justinpc Jan 25 at 8:38

The following function checks whether an expression contains anything of the form f_[___] (i.e. an unevaluated function call), where f is a symbol in the current context1 (to ensure that e.g. Sin[3] is allowed):

functioncall::unev = "Unevaluated function calls!";
check = If[
! FreeQ[#, x_Symbol[___] /; Context@x == $Context, All], Message[functioncall::unev]; #, # ] &; F[x_, y_] := x + y; check[F[1, 0]] (* 1 *) check[F[x, y]] (* x + y *) check[G[x, y]] (* functioncall::unev: Unevaluated function calls! *) (* G[x, y] *) check[F[0]] (* functioncall::unev: Unevaluated function calls! *) (* F[0] *)  If you want to apply this function to every output, you can assign the function check to $Post:

$Post = check;  1 The terms "context" and "delayed evaluation" have different meanings in the context of Mathematica than what you seem to think: What you call "context", I would call "(kernel) session" (see $Context for what context means). What you call "delayed evaluation", I would call "inert expression" (delayed evaluation is used more in the context of evaluating the r.h.s of SetDelayed, TagSetDelayed and RuleDelayed)

• Thanks. That seems to do the job. It is a shame that this isn't provided as a language construct. Just one question: isn't the All argument implicit in FreeQ? – justinpc Jan 24 at 13:52
• @justinpc I don't think it would really go with the "spirit" of Mathematica. The big advantage is you can use symbolic expressions in the same way as actual numbers. (If you simply want to ensure that you get a number, see NumericQ) – Lukas Lang Jan 24 at 13:56
• I will also edit my question a bit to coincide with the context of your answer. Another question: "inert" does not seem to be a term in the Mathematica documentation. Do you have a more contextual term for this? Right now I am leaning towards "unevaluated function application". – justinpc Jan 24 at 13:56
• Yes, I had the same feeling regarding the spirit issue. It's a tough question. Mathematica provides facilities both for symbolic manipulation, but it also has "Programmatic Notebooks" and facilities for multiple different scoping paradigms. What we are talking about here are in fact multiple different evaluation paradigms. – justinpc Jan 24 at 13:59

You could define

symbol[___]:=$Failed  For every existing symbol from Names["*"] or for all that will be created by using $NewSymbol.

But I would not do that globally. There are many use cases for custom expressions that are 'unevaluated' see for example: 11436

What I do is to associate symbol[___]:=\$Failed when I define a function. I do this so often that I have a function for this: MFailByDefault

The definition is at the bottom or you can also install Meh, its parent package: https://github.com/kubaPod/Meh

(*optional package setup*)
ResourceFunction["GitHubInstall"]["kubapod","meh"];
Needs @ "Meh";


foo // ClearAll;
foo[x_, y_] := x + y

foo // MFailByDefault

foo[1, "X", PlotRange -> Automatic]


foo::argpatt: There are no rules associated with signature foo[Integer, String, Rule].

It issues a message because I don't like the silent way functions fail. It also returns a Failure because I prefer checking for failures rather than catching messages.

### Quick definition

MFailByDefault[symbol_Symbol]:= (
symbol::argpatt = Meh::argpatt
; symbol[x___]:= MGenerateAll[symbol::argpatt, inputToSignature[symbol[x]]]
);

inputToSignature // Attributes = {HoldAllComplete};

inputToSignature[head_[spec___]]:= ToString[#, OutputForm]& @ StringForm[
"[]"
`