Re: Problems with lexical scoping
- To: mathgroup at smc.vnet.net
- Subject: [mg108150] Re: [mg108105] Problems with lexical scoping
- From: DrMajorBob <btreat1 at austin.rr.com>
- Date: Tue, 9 Mar 2010 06:23:46 -0500 (EST)
- References: <201003081115.GAA04112@smc.vnet.net>
- Reply-to: drmajorbob at yahoo.com
Test sequence: test = Flatten@{RandomInteger[{0, 1}, RandomInteger[{0, 2}]], RandomReal[{0, 1}, RandomInteger[{1, 3}]], RandomInteger[{0, 1}, RandomInteger[{0, 2}]]} {1, 0.260818, 0.767116, 0} Split into sublists: SplitBy[test, IntegerQ] {{1}, {0.260818, 0.767116}, {0}} Apply a function: f @@ SplitBy[test, IntegerQ] f[{1}, {0.260818, 0.767116}, {0}] Apply another function to the reals: SplitBy[test, IntegerQ] /. x_Real :> g@x {{1}, {g[0.260818], g[0.767116]}, {0}} Do both, in either order: f @@ (SplitBy[test, IntegerQ] /. x_Real :> g@x) f[{1}, {g[0.260818], g[0.767116]}, {0}] (f @@ SplitBy[test, IntegerQ]) /. x_Real :> g@x f[{1}, {g[0.260818], g[0.767116]}, {0}] Bobby On Mon, 08 Mar 2010 05:15:39 -0600, Leonid Shifrin <lshifr at gmail.com> wrote: > 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 > > -- DrMajorBob at yahoo.com
- References:
- Problems with lexical scoping
- From: Leonid Shifrin <lshifr@gmail.com>
- Problems with lexical scoping