I'm wondering how to properly assess the type of arguments passed to functions defined with :=
. I want my functions to be the most efficient, unambiguous and clear as possible.
When hacking together a function, I don't really care about the type of each argument passed to that function. I'll use an example taken from the documentation.
A first function draft would look like this:
>> g[x_] := Prime[x] - x
Which works fine as long as the type of the argument passed to it is compatible with Prime
. The following is inappropriate behaviour, and should be fixed by changing the function definition:
>> {g[10], g["z"]}
<< {19, -"z" + Prime["z"]}
Here's where I don't know how to correctly proceed. Once I make sure my function works, by providing it arguments of the correct type, I can change its definition to
>> g[x_Integer] := Prime[x] - x
or
>> g[x_?IntegerQ] := Prime[x] - x
which both work as expected.
What's the difference between the two definitions, and which one should be used for maximum efficiency, robustness and cleanliness?
Example with one of my functions
This functions generates a set of points that, when passed to Line
, draw a zig-zag. This case is more ambiguous than the previous.
I can define it this way, which works:
>> contactCoordinates[nCtc_Integer, x0_Integer, y0_Integer,
offset_?NumberQ] :=
Table[{x, y0}, {x, x0, offset*nCtc, offset}]~Riffle~
Table[{x, y0 + offset/2}, {x, x0 + offset/2, offset*nCtc, offset}]
I could also replace _Integer
by _?IntegerQ
, with no noticeable difference. The problem is with _?NumberQ
. I can't define the function using offset_Number
- I have either to use offset_?NumberQ
or offset_Real
. Is one better than the other?