Here are some examples that show a difference between Block
and Module
. I hope including many examples in each code is not confusing. I've organized them in a grid to aid the comparison.
Clear[a, x, y, f, ff, g, h];
f = a x^2;
g = a y^2;
h = a z^2;
y = 4;
Grid[{
Thread@HoldForm@{Command, "", x, y, z, a, "", f, ff, g, h'},
Block[{x = 3, y = 5, z, a, ff}, ff = a x^2;
{Block, "", x, y, z, a, "", f, ff, g, D[h, z]}],
Module[{x = 3, y = 5, z, a, ff}, ff = a x^2;
{Module, "", x, y, z, a, "", f, ff, g, D[h, z]}]
}, Dividers -> All]

Below, the Hold[..]
shows the values before evaluation exits the Block
/Module
, and it is followed by what the values evaluate to outside the Block
/Module
. There is no change after exiting Module
, but there can be after exiting Block
. When Block
returns an expression, any blocked variables get their values back and the returned expression is reevaluated.
x = 7;
Grid[{
Block[{x},
{x, f, D[f, x]} // {Block, "", Hold[#], #} &],
Module[{x},
{x, f, D[f, x]} // {Module, "", Hold[#], #} &]
}, Dividers -> All]

Point of comparison:
In Block[]
, the block variables refer to the same variables outside the Block
. However, at the beginning of Block[]
, the values or definitions of the variables are cleared. When Block[]
exits, the block variables are reset to their values or definitions. This may trigger a reevaluation.
In Module[]
, the module variables do not refer to the same variables outside the Module
. Definitions made before the module will refer to variables outside the Module[]
and will not refer to the module variables. In definitions made inside the module, the literal appearance of variables will refer to the module variables. Example:
Clear[a, x, f];
f = a x^2;
Module[{x, ff}, ff = f; {x, ff}] (* no literal appearance of x in "ff = f" *)
Module[{x, ff}, ff = a x^2; {x, ff}]; (* x literally appears *)
(*
{x$27343, a x^2} <-- external x
{x$27344, a x$27344^2} <-- module x
*)
Block[]
is used to prevent a formula from having a value substituted into a variable, either prematurely or at all. This was useful in the second example for finding the derivative. Plot[]
effectively uses Block[]
for this purpose so that x=5; Plot[2 x^2, {x, 0, 2}]
plots the parabola
$y=2x^2$ and not the line
$y = 50$ (the value of
$2x^2$ at
$x=5$).