1
$\begingroup$

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},
 TraditionalForm@TextCell[Column[{
 Row[{x, " = ", 5}]    (*I want x to always be a symbol*)},
 Spacings -> 0.5], "Text", FontFamily -> "Palatino", FontSize -> 18]    ] 
$\endgroup$
4

4 Answers 4

3
$\begingroup$

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

ClearAll["Global`*"];  (* x is unassigned *)
x = 5; (* Global`x is 5 *)
Block[{x}, x] (* 5, use Global`x *)
Block[{x = 0}, x] (* 0 *)
Block[{x}, x = 0] (* 0 *)
x (* 5; Global`x 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?

$\endgroup$
2
$\begingroup$

Example 1:

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

Output: enter image description here

Explanation:

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

Example 2 (I added "Print[f]"):

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

enter image description here

And if x has a global value:

enter image description here

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}, 
 TraditionalForm@
  TextCell[Column[{Row[{x, " = ", 
        5}] (I want x to always be a symbol)}, Spacings -> 0.5], 
   "Text", FontFamily -> "Palatino", FontSize -> 18]]

Output: enter image description here

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.

$\endgroup$
2
$\begingroup$

(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]

This might have undesirable implications if you do further processing of the result, but I would need more information to help you address any of those issues.

Extra info about Block

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}}

$\endgroup$
1
$\begingroup$

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

Block[{x},
  ToBoxes@TraditionalForm@TextCell[
     Column[{Row[{x, " = ", 5}]  (*I want x to always be a symbol*)},
      Spacings -> 0.5],
     "Text",
     FontFamily -> "Palatino", FontSize -> 18, CellContext -> Cell]
  ] // RawBoxes

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.

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$
    – Michael E2
    Jun 10, 2022 at 21:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.