1.) In a function definition, e.g.
f[a_Real, b_Integer, c_:False]:=
Print["function f called with Real argument a=", a
, ", b=", b
, ", c=", c
];
the third parameter can be given a default value and it can be called with one less parameter. In the example the default is False
.
f
remains unevaluated, if the first parameter does not have Head Real
OR if the second one does not have Head Integer
. But for the third one there is no type checking:
(* Tests... *)
f[1, 2, True] (* remains unevaluated because first argument is not Real *)
f[1.0, 2, True]
f[2.0 ,2 ]
f[3.0, 3, 4]
All but the first test evaluate with the Print
statement from the definition of f
.
2.) Another way of checking parameters uses property tests whose names usually terminate with a capital Q
, like BooleanQ
, IntegerQ
, LetterQ
, ListQ
, InexactNumberQ
, StringQ
and so on (there is nothing like RealQ
). Before the test function a question mark has to follow the Underline pronounced “blank”:
ClearAll[a,b,c,g];
g[ a_?InexactNumberQ
, b_?IntegerQ
, c_?BooleanQ
] :=
Print["function g called with Real argument a=", a
, ", b=", b
, ", c=", c
];
(* Tests.... *)
g[1, 2, True] (* remains unevaluated: 1 is no Inexact number *)
g[1.0, 2, True] (* evaluates with the Print statement *)
g[2.0, 2] (* remains unevaluated: too few arguments *)
g[3.0, 3, 4] (* remains unevaluated: 4 is not True or False *)
BTW: Would RealQ[x_] := (Head[x] === Real);
be the equivalent for real arguments, akin to IntegerQ
for Integer arguments and BooleanQ
for True/False? How does it differ from InexactNumberQ
? If I ask Mathematica, it can’t decide whether RealQ
as defined above and InexactNumberQ
are the same thing, but for all examples I came up with, both returned the same result.
In the example for g
, only the second test is evaluated because all arguments match their associated property tests. All others remain unevaluated because of a mismatch – as expected.
3.) Yet another way of checking parameters uses property tests or even more complicate test procedures and the construct /;
after the underline, pronounced “provided that”. If one puts the parameter test conditions after the closing bracket of the parameter list, even relations between different parameters become possible: However, writing b_/.(b>a)
inside of the parameter list does not work, because a
is displayed blue or black instead of green, indicating no reference to parameters of the function but rather to another object (if it exists). The third alternative requires a bit more writing, but one can make more elaborate tests on the structure and content of the actual parameters:
ClearAll[a,b,c,h];
h[a_
, b_
, c_/;BooleanQ[c] (* the test for c involves no other parameter, so it may be done here *)
]/;InexactNumberQ[a] && IntegerQ[b] && b>a := (* test involving a and b must be after the bracket *)
Print["function h called with Real argument a=", a
, ", b=", b
, ", c=", c
];
(* Tests... *)
h[1, 2, True] (* remains unevaluated: 1st argument no Inexact number *)
h[1.0, 2, True]
h[2.0, 2, True] (* remains unevaluated because !b>a *)
h[2.0, 3] (* remains unevaluated: too few arguments *)
h[3.0, 4, 5] (* remains unevaluated: 4 is not True or False *)
In the tests, only in the second one, h
, is evaluated because all arguments match their associated property tests. All others remain unevaluated. The result of the tests is:
h[1, 2, True]
function h called with Real argument a=1., b=2, c=True
h[2., 2, True]
h[2., 3]
h[3., 4, 5]
How would one modify my function definition giving a default value for an argument at the end of the argument list such that a given argument matches only if it matches BooleanQ
in my example.
InexactNumberQ
you can useFindInstance[Not[InexactNumberQ[x]], x, Reals]
$\endgroup$0.4 + 0.8*I // InexactNumberQ
isTrue
$\endgroup$NumberQ
you can see that it is equivalent toMatchQ[#,_Integer|_Rational|_Real|_Complex]&
and that excludes objects like Sin[1] with head Sin. Perhaps you would likeNumericQ[#]&&Im[#]==0 &
$\endgroup$FindInstance[Not[InexactNumberQ[x]], x, Reals]
showed that rational numbers like -(12/5) are notInexactNumberQ
and just checking the head you loose expressions likeSin[1]
$\endgroup$