25

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_?...


25

Here is one way: Pattern[#, Blank[]] & /@ {a, b, c, d, e, f, g, h, i, j} (* {a_, b_, c_, d_, e_, f_, g_, h_, i_, j_} *) An inspection of the FullForm of a_ reveals why this works: a_ // FullForm (* Pattern[a, Blank[]] *) We can abbreviate slightly if we realize that the InputForm of Blank[] is _: Pattern[#, _] & /@ {a, b, c, d, e, f, g, h, i, j} ...


22

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.


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[...


17

A few additional alternatives to inject patterns on the rhs: list = {a, b, c, d, e, f, g, h, i, j}; Replace[list, a_ :> (x_ /. x -> a), 1] {a_, b_, c_, d_, e_, f_, g_, h_, i_, j_} Replace[list, a_ :> (Pattern[#, _] &@a), 1] {a_, b_, c_, d_, e_, f_, g_, h_, i_, j_} Activate @ Replace[list, a_ :> Inactive[Pattern][a, _], 1] {a_, b_,...


16

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

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 ...


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

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`"...


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

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)}}


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

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

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]


11

Re 1: As documented in Operator Input Forms, colon represents two different operations: symb:expr Pattern[symb, expr] patt:expr Optional[patt, expr] If you look at the FullForm of your first three examples, you'll see that they follow these forms. The fourth example arguably is a bug. Re 2) No, opts:OptionsPattern[] is not a special form. From the ...


11

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, ...


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

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

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

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

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 ...


10

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]


9

At a minimal level you could discriminate like this f[angle_ n_] := ... f[pt : {_, _}, angle_] := ... But if you want to be really picky, you could limit your pt argument to only except a list of two elements, both of which are numeric objects, but neither of which is a complex number. This can be done by defining a new argument pattern pt2D = {Repeated[...


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] ...


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