I did a handful of tests with Block
, With
, and Module
and had a couple of new surprises. First, I explicitly nested all pairs, producing the following nine tests, naively expecting 37 in each case:
{Block[{x=42}, Block[ {x=37},x]],
Block[{x=42}, With[ {x=37},x]],
Block[{x=42}, Module[{x=37},x]],
With[ {x=42}, Block[ {x=37},x]],
With[ {x=42}, With[ {x=37},x]],
With[ {x=42}, Module[{x=37},x]],
Module[{x=42},Block[ {x=37},x]],
Module[{x=42},With[ {x=37},x]],
Module[{x=42},Module[{x=37},x]]}
During evaluation of In[48]:= Block::lvset: Local variable specification {42=37} contains 42=37, which is an assignment to 42; only assignments to symbols are allowed. >>
Out[48]= {37, 37, 37, Block[{42 = 37}, 42], 37, 37, 37, 37, 37}
The surprise is that With...Block...
produces a collision, but With...With...
and With...Module...
don't.
UNLESS, I try the test this way
With[{heads={Block,With,Module}},
Table[heads[[i]][{x=42},heads[[j]][{x=37},x]],{i,3},{j,3}]]
During evaluation of In[49]:= Block::lvset: Local variable specification {42=37} contains 42=37, which is an assignment to 42; only assignments to symbols are allowed. >>
During evaluation of In[49]:= With::lvset: Local variable specification {42=37} contains 42=37, which is an assignment to 42; only assignments to symbols are allowed. >>
During evaluation of In[49]:= Module::lvset: Local variable specification {42=37} contains 42=37, which is an assignment to 42; only assignments to symbols are allowed. >>
Out[49]= {{37, 37, 37}, {Block[{42 = 37}, 42], With[{42 = 37}, 42],
Module[{42 = 37}, 42]}, {37, 37, 37}}
in which case ALL the With...
cases produce collisions.
I thought I was starting to understand MMA's scoping constructs :(
EDIT: in case my question wasn't clear, I'd be grateful for the following explanations in more detail than the documentation offers: (1) why x
collides in the explicit With...Block...
case, (2) why x
collides in two more cases when the nesting constructs are built using Table
instead of explicitly.
it occurred to me late to include Function
and Table
in the mix of scoping constructs, since they also give temporary bindings to variables. But I haven't tried that yet.
With
-Block
situation is pretty clear, when you look at the trace:Block[{42 = 37}, 42]
. TheWith
-With
situation is explained in the more information doc. $\endgroup$