The Stack Overflow podcast is back! Listen to an interview with our new CEO.
24

Ramblings Arguments of the left-hand-side head are evaluated in the course of function definition, therefore you can use a utility function that constructs the patterns that you want. For example: SetAttributes[nq, HoldFirst] Quiet[ nq[s_Symbol] := s_?NumericQ ] Now: ClearAll[f] f[nq @ a, nq @ b, nq @ c] := a + b + c Definition[f] f[a_?NumericQ, b_?...


22

Edit: It was pointed out that the original form is not bullet-proof, e.g. GraphicsPrimitiveQ /@ {InputNotebook, Unique, Sequence} all returned True. However, when looking upon this answer about generating new graphics primitives, a superior answer came to light: Clear[GraphicsPrimitiveQ]; GraphicsPrimitiveQ[s_Symbol | (s_)[___]] := 0 < Count[DownValues[...


21

You need Except: f[a : Except[_Integer]] := 2 a In addition to being concise, this has an advantage that you can use it in functions which hold their arguments, and don't need to worry about evaluation leaks, since this test is done entirely by the pattern-matcher. For this reason, this is also more efficient than testing head explicitly.


14

I have moved the large addendum from my answer to How to program a F::argx message? to this post as I believe it is a better fit here. Please see that link for basic information before continuing. Handling multiple messages with an auxiliary function For full control of Message generation while retaining the canonical behavior of returning an unmatched ...


14

The Documentation states (emphasis is mine): Pattern (:): s:obj represents the pattern object obj, assigned the name s. Optional (:): p:v is a pattern object that represents an expression of the form p, which, if omitted, should be replaced by v. I think that the Documentation page for Optional is misleading since it states that the infix operator for ...


13

This has nothing to do with PatternSequence rather the problem is with how you use Repeated (..). Take for example the following function definition: f[x : {{_, _} ..}] := Norm[N[x]] Now if we feed it the following input: f[{{1, 1}, {1, 2}, {1, 3}}] The function works as expected and yields: 4.07914333 Now let's redefine the function as follows (we use ...


13

Well, the documentation of ValueQ states ValueQ gives False only if expr would not change if it were to be entered as Wolfram Language input. This explains pretty much everything you are experiencing. Very easy example: Hold[1/2]//FullForm (* Hold[Times[1,Power[2,-1]]] *) You see that you enter 1/2 as a multiplication but what if we don't hold it? See ...


13

With the definition f[x_List] := x + 1 you create a substitution rule that can only be applied when the argument of f is a List. In all other cases the function remains unevaluated. If instead you want to see an error message, or maybe no output, or whatever, you have to define a substitution rule for f that is applied in all other cases. That is most ...


12

See @AlbertRetey's answer for all but trivial cases. Don't use Optional, nor If. Use two definitions. similarWords[string_] := Nearest[WordList[], string] similarWords[string_, n_] := Nearest[WordList[], string, n] I prefer this over just using arg___ and passing all arguments into Nearest because it keeps the responsibility for argument checking with ...


11

Leonid's answer is the best I think, but Nasser's method in a comment is also valid. It is based on the precedence of rules. If you define a behavior for the Head you don't want you can use a fall-through definition for everything else, e.g.: f[a_Integer] := 2 a f[a_] := {1, 2, 3}^a f /@ {4, 3.14, 3/5} {8, {1, 8.81524, 31.4891}, {1, 2^(3/5), 3^(3/5)}}


11

If your definitions are exactly like you show, every time, you can use belisarius's method, slightly refined: g[x_Integer] := x + 1 g[s_String] := s <> "!!!" (DownValues@g)[[All, 1, 1, 1, 2, 1]] {Integer, String} However this is fragile in that it will fail if your definitions are different, e.g.: g[r_ /; Head[r] === Real] := r + Pi g[a_List?...


11

Implementation This is indeed an important problem. It is usually best to have a separate function testing various options. Here is the solution I propose: a wrapper that would factor out the testing functionality from the main function. Here is the code: ClearAll[OptionCheck]; OptionCheck::invldopt = "Option `1` for function `2` received invalid value `3`"...


11

In general there are multiple reasons why a function could fail and it would be better to know the specific reason--particularly if it has been some time since the code was written. See the documentation for Message Clear[f] f[x_] /; If[Head[x] === List, True, Message[f::arg, x]; False] := x + 1 f::arg = "The argument `1` is not a list."; f[{1, 1}] (...


11

If you want to name your variables, but don't want to repeat the pattern test ?NumericQ for each variable, you can use PatternSequence: f[PatternSequence[a1_, a2_, a3_, a4_, a5_]?NumericQ] := {a1, a1+a4, a2+a3, a5} Check: f[1,2,3,4,5] f[1,2,a,4,5] {1, 5, 5, 5} f[1, 2, a, 4, 5]


10

Preamble There are a number of meanings to the word polymorphism. I will give a couple of examples for each. Although my answer may somewhat overlap with other posts, I hope it may still be of some value. Ad hoc polymorphism (function overloading) What you asked for and for what you have received answers is an ad-hoc polymorphism, which basically is ...


10

You can use PatternSequence: f[PatternSequence[x_,y_,z_]?NumericQ, PatternSequence[k_,l_]?IntegerQ] := stuff[x,y,z,k,l] Check: f[1,2,3,π,5] f[π,1,2,3,4] f[1, 2, 3, π, 5] stuff[π, 1, 2, 3, 4]


10

The answer to the question depends upon what exactly should be called as "graphics primitive". In this answer from the practical point of view I define it as a container which can be found inside of Graphics or Graphics3D, which draws something and is not a graphical directive or Dynamic wrapper. This definition differs from the usual meaning but covers all ...


10

With WolframLanguageData your list of graphics primitives will stay up to date. ListOfGraphicsPrimitives[] = Symbol /@ WolframLanguageData[ EntityClass["WolframLanguageSymbol", {"FunctionalityArea","GraphicsPrimitiveFunctions"}], "Name"] {AASTriangle, AffineHalfSpace, AffineSpace, Annulus, Arrow, ASATriangle, Ball, BezierCurve, BSplineCurve, ...


10

Without thinking about any consequences, one idea popped into my mind. First, your definitions for f with the DownValues. I made it a bit more interesting: ClearAll[f]; f // Attributes = {HoldAll}; f /: HoldPattern[f[x_] + f[y_]] := upvaluesSeen[f[x], f[y]]; f[x_] := downvalue[x] How about a small wrapper function that temporarily deletes all DownValues of ...


10

for your simple example Szabolcs suggestions is certainly the best you can do. If for some reason in a less simple situation you want the behavior you described with just one definition this is what you could do: similarWords[string_, n_: Automatic] := If[n === Automatic, Nearest[WordList[], string], Nearest[WordList[], string, n] ] note that Automatic ...


10

I think the easiest way is to use Condition which has the operator form /;. f[x_ /; -1 <= x <= 1, c_] := -(x + c)^2 Then With[{c = -1/4}, Plot[f[x, c], {x, -2, 2}]]


10

FullForm will show you how an expression is really interpreted, In[5]:= FullForm[_.] Out[5]= Optional[Blank[]] This tells you you need to look at Optional and Blank to understand this particular syntax. This is especially important for infix operators like this, because for some the F1 documentation search doesn't bring up a relevant page. Take the ...


9

I was going for a syntactic pattern thing, but actually the two-argument form of MatrixQ should work here: f[x_?(MatrixQ[#,NumberQ]&)] MatrixQ[expr,test] gives True only if test yields True when applied to each of the matrix elements in expr.


9

I'd love to have a short syntax form for that. I'd use it more often: similarWords[string_, n:(_|PatternSequence[]) ]:= Nearest[WordList[],string,n]


9

x_Integer is a pattern which catches an x so long as the Head of x is identical to Integer. Booleans have no such head: {Head[True], Head[False]} {Symbol, Symbol} Thus, x_Boolean will not match True or False, since Symbol is not identically equal to Boolean. You may instead use x_?BooleanQ, which is a pattern which catches an x so long as BooleanQ[x] ...


9

In M9 and earlier, the default value must match any pattern restrictions. In your example, the head of the default is not Integer, and so the default value could never be triggered. In either 10.2 or 10.3 the pattern matcher was relaxed so that the default value no longer needed to match pattern restrictions.


9

From my own comment: You're mixing the concepts of pure functions (# and &) with replacement (/., ->, :>). Use slots with the first one, use patterns (Pattern in the documentation, x_ or x__ for example in usage) with the second. For this problem: f[a, b, c, d] /. f[x__] :> g[x, e] g[a, b, c, d, e] Note the use of __, which is two ...


8

Patterns in Alternatives are tried in order Only the first pattern that matches is "applied" to the expression. Cases does not support multiple patterns outside of Alternatives. I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time. You could of course search with multiple passes: expr = f[x,...


8

Look at the DownValues of f to see how Mathematica will proceed: DownValues[f] {HoldPattern[f[{a_, b_}]] :> a, HoldPattern[f[a_]] :> a} OR ?f So, though you defined f[a_] := a first, the other definition is more specific, hence is applied first. If Mathematica cannot decide it will use the definitions in the order they were entered. From the ...


Only top voted, non community-wiki answers of a minimum length are eligible