MathGroup Archive 2010

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

Search the Archive

Problems with lexical scoping

  • To: mathgroup at smc.vnet.net
  • Subject: [mg108105] Problems with lexical scoping
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Mon, 8 Mar 2010 06:15:39 -0500 (EST)

Hi everyone,

I have encountered a behavior which seems to me like a bug in the
implementation of the lexical scoping of either Function or RuleDelayed or
both.

Here is a toy problem: given a list where I may have some number (possibly
zero) of consecutive integers at the beginning end at the end, and some
(nonzero) number of consecutive reals in the middle, I want to

1. Deconstruct the list into these 3 groups and be able to apply some
function of my choice, taking 3 arguments, to the result.

2. Use the above to apply some arbitrary function to the reals in the
middle.

Here is my implementation:

ClearAll[deconstruct, applyToReals, applyToRealsAlt];
With[{valuePattern  = {(_Integer | _Real) ..}},

 deconstruct[decF_, values : valuePattern] :=
  values /. {leftInts : _Integer ..., reals : _Real ..,
     rightInts : _Integer ...} :>
    decF[{leftInts}, {reals}, {rightInts}];

 applyToReals[f_, values : {_Integer ..}] := values;
 applyToReals[f_, values : valuePattern] :=
  deconstruct[
   Function[{leftInts, reals, rightInts},
    {leftInts, f[{reals}], rightInts}], values];

 applyToRealsAlt[f_, values : {_Integer ..}] := values;
 applyToRealsAlt[f_, values : valuePattern] :=
  deconstruct[
   Function[{leftIntsLoc, realsLoc, rightIntsLoc},
    {leftIntsLoc, f[{realsLoc}], rightIntsLoc}], values];
 ]; (* End external With *)

Note that the functions <applyToReals> and <applyToRealsAlt> only differ in
the names of variables of internal Function, so I'd expect identical
behavior for them, regardless of where they are used, if the lexical scoping
is working properly. Now please observe:

In[136]:=
test = {1, 2, 3, 3.5, 4.0, 4.5, 5, 6, 7}

Out[136]= {1, 2, 3, 3.5, 4., 4.5, 5, 6, 7}

In[139]:= applyToReals[f, test]

During evaluation of In[139]:= Function::flpar: Parameter specification
{1,2,3,3.5,4.,4.5,5,6,7} in
Function[{1,2,3,3.5,4.,4.5,5,6,7},{1,2,3,f[{3.5,4.,4.5}],5,6,7}] should be a
symbol or a list of symbols. >>

During evaluation of In[139]:= Function::flpar: Parameter specification
{1,2,3,3.5,4.,4.5,5,6,7} in
Function[{1,2,3,3.5,4.,4.5,5,6,7},{1,2,3,f[{3.5,4.,4.5}],5,6,7}] should be a
symbol or a list of symbols. >>

Out[139]=
Function[{1, 2, 3, 3.5, 4., 4.5, 5, 6, 7}, {1, 2, 3,
   f[{3.5, 4., 4.5}], 5, 6, 7}][{1, 2, 3}, {3.5, 4., 4.5}, {5, 6, 7}]

In[142]:= applyToRealsAlt[f, test]

Out[142]= {{1, 2, 3}, f[{{3.5, 4., 4.5}}], {5, 6, 7}}

To me this looks like a clear case of  inappropriate variable capture: the
names of variables in internal Function in <applyToReals>  happen to be the
same as those used in <deconstruct> to deconstruct the list, and are
captured by Function before it binds those symbols.

In the alternative version, the names are different and everything is as
expected. But I'd expect things to work also in the first case - the fact
that they don't is an indication to me that a lexical scope is broken for
this particular use case. Tracing shows that both RuleDelayed and Function
do rename their variables, but in the same way, so the name collision still
happens - perhaps this (plus the fact that RuleDelayed does not respect the
inner scoping constructs in terms of name collisions) is the origin of the
problem?

Just to make myself clear, I am not looking for a solution to this toy
problem that would work, I just want to understand the reason for this
behavior, particularly to know whether I am missing something (perhaps using
things inappropriately) or this is indeed a bug.

Thanks in advance.

Regards,
Leonid



  • Prev by Date: Re: Re: Re: Re: learning calculus through mathematica
  • Next by Date: Re: Conjugate of symbolic expressions
  • Previous by thread: Re: find index in an array
  • Next by thread: Re: Problems with lexical scoping