MathGroup Archive 2010

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

Search the Archive

Re: locally changing Options

  • To: mathgroup at smc.vnet.net
  • Subject: [mg108391] Re: locally changing Options
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Tue, 16 Mar 2010 04:45:24 -0500 (EST)

Hi Raffy,

Thanks for your input as well.

I also think that the alternative you mentioned would be quite useful.
Actually, my wish to have an Unblock operation comes from the same desire
to be able to access "previous" values of a symbol, perhaps by fully
qualified symbols inside the Block, or perhaps by some other means.

Regards,
Leonid


On Sun, Mar 14, 2010 at 9:05 PM, Raffy <adraffy at gmail.com> wrote:

> On Mar 14, 3:34 am, Leonid Shifrin <lsh... at gmail.com> wrote:
> > Hi,
> >
> > > Anyway, after thinking about it, I felt that the simple fix would be:
> > > Block[{RowReduce=System`RowReduce[#1,Method->...,##2]&}, ...]
> >
> > In[107]:= Print === System`Print
> >
> > Out[107]= True
> >
> > (I ran this code before running your example with Temp`Print, after which
> > Print got shadowed and this gave False).
> >
> > Since Block scopes dynamically, it obeys the same rules. The scoped
> symbo=
> l
> > is the one currently first on the $ContextPath (if it exists in the
> symbo=
> l
> > table), while the value it is assigned during the initialization in Block
> > can be anything, including the symbol itself.  My guess is that droppin=
> g the
> > fully qualified name in the Trace is just the usual output formatting:
> > behind the scenes we always deal with System`RowReduce (or whatever our
> > symbol is). In particular:
> >
> > In[108]:= Block[{RowReduce},
> >  Context[RowReduce]]
> >
> > Out[108]= "System`"
> >
> > > However, this also results in recursion.  Something seems odd: how is
> > > the blocked RowReduce scoping the fully qualified symbol
> > > System`RowReduce? (Looking at the Trace, it appears that it is
> > > dropping the System` context prior to evaluation...)
> >
> > The statement Block[{x=x}, body] seems to make sense only if x has a gl=
> obal
> > OwnValue, otherwise (if it has DownValues or other ...Values instead) it
> > seems idle to me - that is, equivalent to just Block[{x}, body]. So, for
> =
> the
> > purposes of Block Print and System`Print are identical - that is, the
> cod=
> es
> >
> > Block[{Print = System`Print}, Print[1]];
> > Block[{System`Print = System`Print}, Print[1]];
> > Block[{Print = Print}, Print[1]];
> > Block[{Print}, Print[1]];
> > Block[{System`Print}, Print[1]];
> >
> > are all equivalent (assuming you did not shadow System`Print by importing
> > some context with another Print). The printing happens not inside the
> Blo=
> ck
> > anyway (since inside the Block Print forgets what it is), but the moment
> =
> we
> > leave it. Proof:
> >
> > In[109]:=
> > ClearAll[f];
> > f[Unevaluated[Print[x_]]] := {"Value: ", x};
> >
> > In[111]:= Block[{Print = System`Print}, f[Print[1]]]
> >
> > Out[111]= {"Value: ", 1}
> >
> > Since <f> does not hold its arguments,  Print[1] would evaluate if it P=
> rint
> > "knew what to do", and the rule in <f> would not match, just as it
> happen=
> s
> > below, without the Block:
> >
> > In[112]:= f[Print[1]]
> >
> > During evaluation of In[112]:= 1
> >
> > Out[112]= f[Null]
> >
> >
> >
> > > This works: Block[{Print=System`Print},Print[1]];
> > > This doesn't: Block[{Print=System`Print[##] &}, Print[1]];
> >
> > This has probably nothing to do with Block specifically, and can be
> model=
> ed
> > in a simpler setting.
> >
> > Here we model the code <Block[{Print = Print}, Print[1]]>
> >
> > In[113]:=
> > Clear[f];
> > f = f;
> > f[1]
> >
> > Out[115]= f[1]
> >
> > and here the code <Block[{Print = Print[##] &}, Print[1]]>
> >
> > In[116]:= Clear[f]
> > f = f[##] &;
> > f[1]
> >
> > During evaluation of In[116]:= $IterationLimit::itlim: Iteration limit =
> of
> > 4096 exceeded. >>
> >
> > Out[118]= Hold[f[1]]
> >
> > This suggests that  this effect is due to the differences in evaluation=
>  in
> > these two cases, rather than specifically tied to Block. In the second
> > method, infinite iteration is likely due to the fact that expression is
> > oscillating between the forms  f[1] and f[##]&[1]: after each
> > parameter-passing stage, evaluator gets a new expression (f[1] instead of
> > f[##]&[1]), and since it has changed, evaluator re-evaluates it, which
> ag=
> ain
> > results in f[##]&[1].
> >
> >
> >
> > > Really odd behavior can be found using the following:
> > > Let $ContextPath = { ..., "Temp`", ..., "System`", ... }
> > > Block[{Temp`Print=System`Print[1, ##] &}, Print[2]] will print "12"
> > > and also cause Print to become shadowed.
> >
> > Indeed, odd enough. If a symbol did not exist in some context, but we
> dec=
> ide
> > to use it in Block, I'd expect Block to clean up, namely return
> everythin=
> g
> > to the way it was before Block has been called. In particular, it should
> > have removed this symbol from the symbol table at the end, so that there
> > would be no shadowing after Block has finished. The question is whether
> t=
> his
> > is a bug or a feature (intended design decision) - I have no idea alas.
> >
> > Regards,
> > Leonid
> >
> >
> >
> >
> >
> > > I guess the problem boils down to: Why does System`Print simplify to
> > > Print?
>
> Leonid thanks for all the input.  However, not to beat a dead horse,
> I'd like make another point.
>
> I thought Block[ {x = ...}, body ] was the equivalent of:
>
> Block$1234`x = ...
> $ContextPath = Prepend["Block$1234`", $ContextPath];
> body
> $ContextPath = Rest[$ContextPath];
> Remove["Block$1234`*"];
> (which would be essentially how dynamic scoping in general is
> performed: you pushing a new resolver on your lookup stack.)
>
> That way, if body was, Print[x + 1], x gets resolved to Block$1234`x
> and prints 2.
>
> Or, with my example from before:
> Block$1234`f = System`f[1, ##]&;
> $ContextPath = Prepend["Block$1234`", $ContextPath];
> Print[f[2]];
> $ContextPath = Rest[$ContextPath];
> Remove["Block$1234`*"];
>
> Where f[2] => Block$1234`f[2] => System`f[1,2]
>
> But it appears that Block[ {x = ...}, body ] is instead figuring out
> which long variable it's scoping based on the current context and then
> blocking that.
>
> While they gives a similar effects, it seems the latter is far less
> useful, because the programmer loses the ability to reference a symbol
> with a fully known context path. (It also seems like you could create
> a really nasty example of nested Blocks with Context changes but I
> can't think of it right now.)
>
> It's good that I now know Block[] is not doing what I expected, I just
> wished it performed like my first example.  This would give the
> programmer the ability to "unblock" by just using the long symbol
> name.
>
>


  • Prev by Date: Re: Pi day
  • Next by Date: Re: Pi day
  • Previous by thread: Re: locally changing Options
  • Next by thread: bad Mathieu functions