Re: locally changing Options
- To: mathgroup at smc.vnet.net
- Subject: [mg108330] Re: locally changing Options
- From: Leonid Shifrin <lshifr at gmail.com>
- Date: Sun, 14 Mar 2010 05:12:55 -0500 (EST)
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 symbol is the one currently first on the $ContextPath (if it exists in the symbol table), while the value it is assigned during the initialization in Block can be anything, including the symbol itself. My guess is that dropping 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 global 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 codes 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 Block 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 Print "knew what to do", and the rule in <f> would not match, just as it happens 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 modeled 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 again 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 decide to use it in Block, I'd expect Block to clean up, namely return everything 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 this 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? > >