A common Mathematica-related question concerns the difference between Module
,
Block
, and With
. Here is a small example which illustrates those differences:
x = 1; y[] := x
{ Module[{x = 2}, {"Module", x, y[], Hold[x]}]
, Block[{x = 2}, { "Block", x, y[], Hold[x]}]
, With[{x = 2}, { "With", x, y[], Hold[x]}]
} // TableForm
A close study of the results might help to build an intuition about the differences:
Module 2 1 Hold[x$561]
Block 2 2 Hold[x]
With 2 1 Hold[2]
In all three cases, the local value of x
is the same: 2
. So all three constructs are the same with respect to the purpose of creating local variables. However, they differ in other respects.
Module
Module
localizes the symbol x
so that it is distinct from the global x
. It does this by generating a new unique symbol and then using the new symbol in place of the original x
. Thus, the Module
expression is effectively the same as if we had typed:
x$561 = 2; {"Module", x$561, y[], Hold[x$561]}
The generated symbols are generally temporary and disappear when they are no longer needed, although there are circumstances in which they will stay around (both intentional and inadvertent).
Block
Block
does not localize the symbol x
. Instead, it temporarily clears all definitions and attributes associated with the symbol, evaluates the body, and then restores the cleared definitions and attributes. Thus,
the Block
expression is effectively the same as:
ClearAll[x]; x = 2; {"Block", x, y[], Hold[x]}; x = 1
Since the global value of x
has been changed, y[]
will return the new "local" value. This behaviour can be surprising and unexpected, so one should be sure that this is the intent before using Block
-- or be careful to only block symbols that are not used in any other definitions.
With
With
does not localize the symbol x
either. Instead, it replaces all occurrences of x
within the body of the expression with the supplied value. The body is evaluated after this replacement has occurred. Thus,
the With
expression effectively is the same as:
{"With", 2, y[], Hold[2]}
Note that With
is unique among the three constructs in that it will
insert values into held expressions (Hold[x]
in this case). This has
utility when generating code.