Skip to main content

pattern matching - Assessing argument type in set delayed function definitions


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?





  1. http://reference.wolfram.com/mathematica/tutorial/PatternsForSomeCommonTypesOfExpression.html

  2. Functions vs. patterns

  3. https://stackoverflow.com/q/8922966/1142160




Comments

Popular posts from this blog

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...