When I want to define a function that uses a pattern, how should I localize the pattern name (i.e., x_ localizing the symbol x)? I have traditionally used Module but Workbench seems to freak out at times that I have unused symbols. Is this just a bug in Workbench, or is there a proper way of doing this?


So I have been a bit vague in exactly what I mean. To clarify, suppose I make a function in Workbench as:

test[g_, f_] :=
        g /. f[x_] :> x

I will have an error on the Module line stating "the local variable 'x', is not used". Please note this example is just to give the bare minimum so that I get the Workbench error, and to illustrate what kind of localization I mean. That is I want to use a symbol for use in a pattern label, not as a variable.

  • $\begingroup$ In what way does Workbench "freak out"? $\endgroup$ – sebhofer Oct 22 '12 at 19:11
  • $\begingroup$ please see the expanded explanation. $\endgroup$ – Gabriel Oct 22 '12 at 19:50
  • 1
    $\begingroup$ Since you're using RuleDelayed, it is also localized and you don't have to write Module[{x},... $\endgroup$ – rm -rf Oct 22 '12 at 19:55
  • $\begingroup$ ahhh I didn't realize that. Thanks! $\endgroup$ – Gabriel Oct 22 '12 at 19:58

Considering your update, I'd like to point out that RuleDelayed or :> also localizes its symbols, so there is no need to use Module or any other construct to force localize them. For example:

x = 1;
{1, 2, 3} /. x_?EvenQ :> "foo"

(* {1, "foo", 3} *)

Also, the documentation for RuleDelayed says this:

Module and With do not affect local variables of RuleDelayed:

 With[{x = 1}, a /. x_ :> x + 1]
 (* 1 + a *)

Taking that example a bit further, you can see from the following that inside the scope of RuleDelayed, the definition of x in Module is disregarded (it really is x$foo), but outside its scope, the definition in Module kicks in:

Module[{x = b}, (a /. x_ :> x + 1) x]
(* (1 + a) b *)
| improve this answer | |
  • $\begingroup$ I see you beat me while I was working on my edit. Well played. :^) $\endgroup$ – Mr.Wizard Oct 22 '12 at 20:05
  • 2
    $\begingroup$ Oh, yes; most certainly a planned chess move =) I first left it merely as a comment under the question, but then saw who wrote the incomplete answer below and just had to make my play :D I would say checkmate, but I don't have 37k... $\endgroup$ – rm -rf Oct 22 '12 at 20:08

When you define a function using := such as:

f[x_] := Sin[x] + 5

The x is automatically localized. Every appeareance of x on the right-hand side of := will be replaced with the argument of f, regardless of any value assigned to Global`x (since Global is the default context this just means e.g. x = 1).

You cannot however do something like this:

f[x_] := (x = Mod[x, 2]; x^2)


Set::setraw: Cannot assign to raw object 7. >>


This happens because as stated above x = Mod[x, 2] becomes 7 = Mod[7, 2]. Now Module is appropriate.${}{}{}$ We introduce a temporary symbol t and make assignment to that:

g[x_] := Module[{t}, t = Mod[x, 2]; t^2]


Your updated question has an example that includes a third kind of localization: RuleDelayed (:>).

Much as the definition with SetDelayed (:=) when you create a rule such as f[x_] :> x the x is localized. You therefore have three different localizing constructs in this code:

test[g_, f_] :=
        g /. f[x_] :> x

g and f by :=, one x by Module, and another x by :>.

| improve this answer | |
  • $\begingroup$ @Fred thanks for the typo fix. I hate this keyboard! :-p $\endgroup$ – Mr.Wizard Oct 22 '12 at 19:58
  • $\begingroup$ Cool explanation of the symmetry with := thanks! $\endgroup$ – Gabriel Oct 22 '12 at 23:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.