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.