# How to enable automatic “grammar check” for MMA? [duplicate]

The special evaluation mechanism of MMA might make it more likely for MMA users (especially new users) to make mistakes and more difficult to find them.

For example, one may have defined a function

MyFunction[x_Integer, y_String] := ...


and then mistakenly use it as

MyFunctin[1, "test"]


While in other languages one will certainly get an error message, it is not the case in MMA, where the undefined MyFunctin[1, "test"] will remain unevaluated without casing any error message.

Of course, some will argue that this kind of error can be easily spotted in the front-end because of the code highlighting feature, where undefined symbols will be coloured differently. However, if the user mistakenly use

MyFunction["test", 1]


the highlighting will not help.

It is possible to detect errors like this. For example, when the function MyFunction[1, "test"] is called, DownValues[MyFunction] is checked to see if any pattern in it can match MyFunction[1, "test"]. If DownValues[MyFunction] is an empty list (which means the function called is not defined) or no patterns in the DownValues[MyFunction] matches MyFunction[1, "test"], then there is a mistake.

The problem is that the mechanism described above cannot handle more complicated cases. For example, if we use MyFunction[2-1, "tes" <> "t"], there is no way to check if the function call is legitimate unless we evaluate all the arguments in it. So the idea is to check this during the evaluation. For the built-in functions, MMA seems to be able to check this during the evaluation. For example if one mistakenly uses StringJoin[1, "2"], there will be an error message showing "String expected at position 1 in StringJoin[1]".

My question is, how to enable such grammar check mechanisms for custom functions?

## marked as duplicate by m_goldberg, dr.blochwave, MarcoB, Jens, LLlAMnYPOct 4 '15 at 21:21

• You can make additional definitions for MyFunction which will match the incorrect cases, e.g. MyFunction[___] := (Message[...]; \$Failed). There are many ways to do this, and I won't comment on what's best or easiest because I don't know ... – Szabolcs Oct 4 '15 at 12:43
• – Szabolcs Oct 4 '15 at 12:44

I think the best you can do is to put the test in the function defintion and allow all arguments:

MyFunction[x___] := If[Length[{x}] =!= 2, Error,
If[IntegerQ[#] && StringQ[#2] &[x], 32, Error]]

MyFunction[2, "test"]
MyFunction["test", 2]