# Trouble understanding the local variables of the Block command

Example one:

This is said in the documentation

Block localizes values only; it does not create new symbols

I don't understand the previous sentence

ClearAll["Global*"];
Block[{x}, x]
Block[{x}, Print[x]]


Example two:

This is an example of the documentation, but if one of x or y is global the example does not work

ClearAll["Global*"];
Block[{f = Sin[x + I y]},
ParametricPlot[Evaluate[{Re[f], Im[f]}], {x, -Pi, Pi}, {y, -2, 2}, Mesh -> 10]]


Example three:

I would like the Block to work regardless of whether x is global or not

ClearAll["Global*"];
Block[{x},
Row[{x, " = ", 5}]    (*I want x to always be a symbol*)},
Spacings -> 0.5], "Text", FontFamily -> "Palatino", FontSize -> 18]    ]

• cross-posted here: community.wolfram.com/groups/-/m/t/2547643 Jun 10, 2022 at 18:59
• do I copy my answer, or is the above link the appropriate way to go? Jun 10, 2022 at 19:00
• @lericr you could reference the answer crossposted location in your answer here. I think it would be best to have it available here as well. Jun 10, 2022 at 20:25
• The site's definitive Q&A: mathematica.stackexchange.com/questions/559/… Jun 10, 2022 at 21:15

Your question about Print arises because it evaluates to Null in the global name space.

ClearAll["Global*"];  (* x is unassigned *)
x = 5; (* Globalx is 5 *)
Block[{x}, x] (* 5, use Globalx *)
Block[{x = 0}, x] (* 0 *)
Block[{x}, x = 0] (* 0 *)
x (* 5; Globalx unchanged *)
Block[{x}, Print[x]] (* evaluates to Null; prints x *)


In your second example, the code refers to global values of x and y. Try localizing them:

Module[{f = Function[{x, y}, Sin[x + I y]]},
ParametricPlot[{Re[f[x, y]], Im[f[x, y]]}, {x, -Pi, Pi}, {y, -2, 2},Mesh -> 10]]


In your third example, I'm not sure you can have what you want. I mean, sure you can always have a symbol (just use Module), but it will not be the same as the global symbol. Is there a compelling reason not to use a string?

Example 1:

ClearAll["Global*"]; Block[{x}, x] Block[{x}, Print[x]]


Output:

Explanation:

Block[{x}, x] returns x. Block[{x}, Print[x]] prints x and returns Null. Finally Null and x are multiplied.

 ClearAll["Global*"];
Block[{f = Sin[x + I y]}, ParametricPlot[Evaluate[{Re[f], Im[f]}], {x, -Pi, Pi}, {y, -2, 2},Mesh -> 10]]


And if x has a global value:

Explanation:

"f = Sin[x + I y]" this will localize f and initialize with x+I y. But it will NOT localize x and y. The value of "f" is visible from the Print statement: Sin[x+ I y] or Sin[2 + I y]. The ParametricPlot statementthen uses these values, producing an area in the first case and a curve i the second case.

Example 3 (note, here are typos. It should read:"Global*" and strings are always written inside parenthesis and items inside "Column" must be separated by commas):

ClearAll["Global"];
Block[{x},
TextCell[Column[{Row[{x, " = ",
5}] (I want x to always be a symbol)}, Spacings -> 0.5],
"Text", FontFamily -> "Palatino", FontSize -> 18]]


Output:

Explanation:

X is localized, it does not matter if it has a global value or not. x "=" 5 does not assigne 5 to x as the equal sign is, because of the parenthesis, a string and not an operator. The "Column" command writes two lines. "x" inside the string is simply a character. However, if you do not enclose the string in parenthesis, every word is considered a symbol. Worse, "I" is interpreted as the imaginary unit.

(cross-posted: https://community.wolfram.com/groups/-/m/t/2547643)

You say you "want x to always be a symbol", but all symbols will be replaced with their assigned values (OwnValues) if they exist, so this can't actually be done, per se. What you can do, however, is apply one of the various Hold* functions. Probably HoldForm is what you want in this case, and you don't need the Block for this:

TraditionalForm@
TextCell[Column[{Row[{HoldForm[x], " = ", 5}]}, Spacings -> 0.5],
"Text", FontFamily -> "Palatino", FontSize -> 18]


Inside the Block, x will have its OwnValues temporarily overridden. But once the Block finishes executing the OwnValues for x will revert to its previous value. Execution continues until nothing in the expression changes, so any x remaining after Block finishes will get replaced by the "original" OwnValues definition.

Let's play with this:

x = 7;
Block[{x = 5},
{OwnValues[x], Hold[OwnValues[x]]}]


This returns

{{HoldPattern[x] :> 5}, Hold[OwnValues[x]]}

Now try:

ReleaseHold@%


This returns

{{7 :> 5}, {HoldPattern[x] :> 7}}

For the last problem, you could convert it to boxes inside Block:

Block[{x},

As others have pointed out, if x is allowed to be evaluated outside of Block[{x},...], any value it has will be substituted for it. The InterpretationBox that is constructed for the TextCell has the attribute HoldAllComplete, which prevents x from being evaluated when the boxes are returned from Block.
• By the way, I would use TraditionalForm on the Column[..], not the TextCell[..]. But you could CellPrint the TextCell[..] (if you also change Row[] to x == 5); you can't CellPrint the TraditionalForm@TextCell[..]` nicely. Jun 10, 2022 at 21:35