# Is it necessary to use Print inside a Block? [closed]

If I use a Block with variables already used and ask it to Solve an equation inside the Block, it uses the values given outside the Block. For instance, this gives a numeric answer:

R = 1; L = 3;
Block[{R, L, x}, Solve[R + L x == 0, x] ]

(* {{x -> -(1/3)}} *)


But, if I ask it to Print the result everything is fine:

R = 1; L = 3;
Block[{R, L, x}, Print[Solve[R + L x == 0, x]] ]

(* {{x->-(R/L)}} *)


On the second line of the "Details" of Block it says that

When you execute a block, values assigned to x, y, ... are cleared.

So I would expect that anything executing inside a Block would work with cleared (empty) variables and return an expression, not a number obtained with values given to the variables outside the Block. Is this supposed to happen? Must I always use a Print command for Block to localize the variables?

• This is behaving just as I would expect. Inside the Block, R and L have no value assigned to them. Outside the block, they take their global values. Print outputs the result before R and L revert to their global values. Without knowing what you are trying to achieve, it is difficult to suggest what you should do. Commented Nov 1, 2022 at 23:21
• @mikado Sorry, I've edited my question to reflect what I was expecting to get from ´Block´. Commented Nov 1, 2022 at 23:28
• Inside the Block the variables are cleared. Outside the Block they return to the old values. If you don't want the old values any more, use Clear[R, L]. Commented Nov 1, 2022 at 23:32
• @mikado I don't want the values given outside Block to affect the functions written inside it, but after I'm finished with the Block estructure, I want the values to return to the old values. That is the definition of Block: "Block allows you to set up an environment in which the values of variables can temporarily be changed." and "When you execute a block, values assigned to x, y,... are cleared. When the execution of the block is finished, the original values of these symbols are restored." But this appears to not be working unless I use Print inside the Block. Commented Nov 1, 2022 at 23:39
• @mikado After reading lericr's answer now I see that you were giving me a similar answer but I wasn't versed enough in Mathematica's inner workings to understand it. I am sorry I couldn't understand you earlier. But now I do so, thank you for your effort! Commented Nov 2, 2022 at 22:21

I don't want the values given outside Block to affect the functions written inside it, but after I'm finished with the Block estructure, I want the values to return to the old values.

That is exactly what is happening here. Don't forget that the evaluation engine is still running. When the Block is finished, the expression it emits is {{x->-(R/L)}}, but that expression now gets its turn to be evaluated, and now that we're outside of the Block, the "old" values for R and L are available and so are used.

Mathematica doesn't know that you want to stop evaluating an expression unless you tell it. To tell it to stop evaluating, you can use any of the various Hold* expressions, Unevaluated, Inactive/Inactivate, Defer, etc. But which of those you want depends on your use case.

Just throwing something together with no real reason:

Block[{R, L, x}, HoldForm[Evaluate[Solve[R + L x == 0, x]]]]

• I think I now understand what is happening. The problem for me was that I didn't know that after the Block returns an expression, then "the expression gets its turn to be evaluated". It seems weird to me that this evaluation happens without me requesting it, but I guess this behavior must have its uses for someone... Thank you very much for such clear explanation, lericr!! I will accept the answer soon, if no one gives another explanation. Commented Nov 2, 2022 at 0:05
• You're welcome! Commented Nov 2, 2022 at 0:09
• Evaluation continues until the result no longer changes. Block isn’t a special case. This is just how Mathematica inherently works. Commented Nov 2, 2022 at 15:26
• It's not that the Block was evaluated again, it's just that Block was effecively replaced with its result, and we just continued on with evaluation from there. An If statement does not get evaluated again, but whatever result it produces will be the next thing that gets evaluated. Commented Nov 2, 2022 at 15:30
• Consider this: If[True, 2, 3]*10. The If is just an expression, and once the evaluator gets ahold of it, it will want to replace it if it can. In this case it can, and so If[True, 2, 3] goes poof, and becomes 2. But that 2 is still part of something larger that needs to evaluate, and so we keep going. We get 20, and we keep going. It turns out that raw "atoms" like this evaluate to themselves, so we get 20 again, and now the evaluator realizes that it needs to stop, because otherwise it'd get into an infinite recursion. Commented Nov 2, 2022 at 15:34