MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Localize Pattern variables

  • To: mathgroup at smc.vnet.net
  • Subject: [mg107200] Re: [mg107167] Localize Pattern variables
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Fri, 5 Feb 2010 03:23:24 -0500 (EST)
  • References: <201002041129.GAA00047@smc.vnet.net>

Hi Istvan,

I agree with Szabolcs. Just a couple more comments:

you can protect your symbols from possible global value capture in immediate
rules by wrapping them in Block, if that's what you meant:

In[1] :=
x = 1;
Block[{x}, Range[10] /. x_?IntegerQ -> x^2]

Out[2] =
{1, 4, 9, 16, 25, 36, 49, 64, 81, 100}

The binding is here, but for delayed rules you are limited to operations
which can be performed on the matching elements unconditionally (that is,
without inspecting the matched element), because Rule evaluates its r.h.s.
first and then applies the resulting rule to an expression.

One cheap way to simulate delayed rules with Rule is to wrap it in
Unevaluated:

In[3]:=
Clear[func];
func[x_List]:=ReplaceAll[x,Unevaluated[r_Integer->r+100]]

In[5]:=
r=-100;
func@{1,2,3,4}

Out[7]=
{101,102,103,104}

The two are not completely equivalent however.

Your code with Module did not work because you have to "blind" the Rule
(since it is a scoping construct), This will work:

Module[{r,rule},
  Unevaluated[func[x_List]:=ReplaceAll[x,rule[r_Integer,r+100]]]/.rule
->Rule]

Regarding your comment on Block having a possibility to conflict your
internal variables with some others captured within a dynamic scope: if you
really want, you can avoid this. The following code will take your code and
hunt for assignments in it, modifying them to incorporate Block-s which will
operate on symbols that will be guaranteed to be unique in a given
Mathematica session:

ClearAll[blockUnique];
SetAttributes[blockUnique,HoldAll];
Module[{rule},
    blockUnique[symbs:{__Symbol},code_]:=
      Module@@
        Prepend[Hold[code]/.Rule->
                rule/.z_SetDelayed:>(Unevaluated[
                    z]/.HoldPattern[SetDelayed[x_,y_]]:>
                    SetDelayed[x,Block[symbs,y]]),Unevaluated[symbs]]];


Example:

In[93]:=
Clear[func];
blockUnique[{r},func[x_List]:=ReplaceAll[x,r_Integer->r+100]]

In[96]:=
DownValues[func]

Out[96]=
{HoldPattern[func[x$_List]]\[RuleDelayed]
    Block[{r$83},x$/.\[InvisibleSpace]rule$78[r$83_Integer,r$83+100]]}

Your variable <r> is both renamed to make it unique, and localized
dynamically. For this particular problem, this is perhaps an overkill and
Module-generated lexically-scoped symbols will be enough (although this and
similar constructs can have more advanced uses). But in any case, whatever
we do, we just kind of re-implement the scoping that RuleDelayed gives you
for free, so why not use it.

Regards,
Leonid




On Thu, Feb 4, 2010 at 2:29 PM, Istv=E1n <replicatorzed at gmail.com> wrote:

> Dear Group,
>
> I often write small replacement codes inside (packaged) functions. One
> toy model is like this:
>
> In[78]:= func[x_List] := ReplaceAll[x, r_Integer -> r + 100]; r =.;
> func@{1, 2, 3, 4}
>
> Out[80]= {101, 102, 103, 104}
>
> In[81]:= r = -100; func@{1, 2, 3, 4}
>
> Out[82]= {0, 0, 0, 0}
>
> What is the best way to localize r in func? Obviously modularizing it
> won't solve the matter:
>
> func[x_List] := Module[{r}, ReplaceAll[x, r_Integer -> r + 100]];
>
> produces the very same output. I can also use Block, instead of
> Module, which seemingly works, but then consider this version, where r
> interferes with an in-Block variable of the same name:
>
> func[x_List] := Block[{r}, r = 12; ReplaceAll[x, r_Integer -> r +
> 100]];
>
> Of course I can always use RuleDelayed, but what if I don't want to.
> The embarrassing thing is that I'm pretty sure that before code
> colouring (v6), I missed this intereference quite a few times,
> assuming that lhs pattern variables are automatically bound with rhs
> ones, with a higher priority than assigning the value of existing
> variables of the same name to rhs pattern variables.
>
> How can I restrict (i.e. localize) non-delayed pattern variables to
> rules? Why RuleDelayed makes r local but not Rule? Am I missing
> something? Is there a general way to deal with this matter?
> Thanks
>
> Istvan
>
>



  • Prev by Date: Re: Inserting a position-limited Locator inside a Manipulate multiplot
  • Next by Date: Re: Re: Re: Combining
  • Previous by thread: Localize Pattern variables
  • Next by thread: Re: Localize Pattern variables