3

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?

Edit

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_] :=
    Module[{x},
        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.

Gabriel
  • 2,225
  • 18
  • 19

2 Answers2

8

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 *)
rm -rf
  • 88,781
  • 21
  • 293
  • 472
  • I see you beat me while I was working on my edit. Well played. :^) – Mr.Wizard Oct 22 '12 at 20:05
  • 2
    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... – rm -rf Oct 22 '12 at 20:08
6

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)

f[7]

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

49

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]

g[7]
1

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_] :=
    Module[{x},
        g /. f[x_] :> x
    ]

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

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371