Assert no unevaluated function applications
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
)
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 signaturefoo[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[
"``[``]"
, head
, Row[ Thread @ HoldForm[{spec}][[{1}, ;;, 0]], ", "]
];