MathGroup Archive 2010

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

Search the Archive

Re: locally changing Options

  • To: mathgroup at smc.vnet.net
  • Subject: [mg108356] Re: locally changing Options
  • From: Raffy <adraffy at gmail.com>
  • Date: Mon, 15 Mar 2010 00:05:12 -0500 (EST)
  • References: <hnie2u$et$1@smc.vnet.net>

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: Re: Pi day
  • Next by Date: Re: Trouble with coupled quadratic equations where the
  • Previous by thread: Re: Re: locally changing Options
  • Next by thread: Re: locally changing Options