# About evaluation in Block

I'm completely puzzled by the following codes:

Clear[func, f]
a = x^2 + z;
func[k_] := Block[{f}, (f[x_] := Evaluate[(a /. {z -> k})]; f[1])]
func[2]

2+x^2


But I think it should be 3, i.e., 2+1^2=3.

Actually for the following code:

 f[x_] := Evaluate[(a /. {z -> k})]; f[1]


The output is 3.

Can you explain the evaluation inside the Block?

Taking Simon Woods' advice, for

func[k_] :=
Block[{f, tmp}, (tmp = Evaluate[a /. z -> k]; f[x_] = tmp; f[1])]

Trace[func[2]]


gives,

{func[2],Block[{f,tmp},tmp = Evaluate[a /. z -> 2],f[x_] = tmp; f[1]],...}

But, for the codes

func[k_] := Block[{f}, (f[x_] = Evaluate[a /. z -> k]; f[1])]
Trace[func[2]]


gives,

{func[2],Block[{f},f[x$_] = Evaluate[a /. z -> 2];f[1],...} I notice that the arguments of f inside the Block are different in these two cases, and that is the reason. But why is the difference? - You can do func[k_] := Block[{y = (a /. {z -> k}), f}, (f[x_] = y; f[1])]. – b.gatessucks Jul 18 '13 at 8:05 @b.gatessucks Yes,I've notice this:func[k_] := Block[{f, tmp}, (tmp = Evaluate[a /. z -> k]; f[x_] = tmp; f[1])] But why? – yulinlinyu Jul 18 '13 at 8:07 Have a look at Trace[func[2]] – Simon Woods Jul 18 '13 at 8:09 @Simon Woods, see my edit, I will appreciate your reply. – yulinlinyu Jul 18 '13 at 8:49 ## 1 Answer Nested scoping constructs like Module or SetDelayed apply a variable renaming, adding the symbol ($) to each variable. For that, take a look at the internal form of f, as you defined it

func[k_] := Block[{f},
f[x_] := Evaluate[ReplaceAll[a, {z -> k}]];
Information[f];
Trace[f[1]]]

func[2]

Globalf
f[x$_]:=2+x^2 {f[1], 2+x^2}  the function f accepts any argument and gives the name x\$ to it. Then goes to evaluate the right-hand side and looks for any occurrence of x\$so to make the replacement with 1, in that case. Unfortunately, the global variable a (that defined externally) depends on x and not on x$ so no replacement happens. A possible solution is to change the name of the variable x so to avoid confusion and make clear the replacement of such variable inside the ReplaceAll.

func[k_] := Block[{f},
f[var_] := Evaluate[ReplaceAll[a, {z -> k, x -> var}]];
Information[f];
Trace[f[1]]]

func[2]
Globalf
f[var$_]:=2+var$^2

{f[1], 2+1^2}, {1^2, 1}, 2+1, 3}

-
Block is not to blame for the symbol renaming but the outermost SetDelayed realising that your k is being injected in the innermost SetDelayed – Rojo Jul 19 '13 at 5:01
@Rojo thanks, you are right. My answer is not correct in the explanation. I have to edit it and adjust. Indeed, doing some further tests I can confirm that the nesting of SetDelayed seems to be the cause of the renaming of var to var\$. Honestly I still have to fully understand why, so at a glance I thought it was just Block. – bobknight Jul 19 '13 at 8:37
@Rojo please let me know if I have to delete/edit/add my answer. I'm new on SE. I have seen there is a question with similar issue described: "If you look deep in the examples in the reference page for Module, under the section labeled Possible Issues, there's a little note that says "Variables are renamed in nested scopes"". – bobknight Jul 19 '13 at 9:10
Sure, when you see a way to improve or correct your answer its better if you edit it. Welcome to SE :) – Rojo Jul 19 '13 at 17:10
To correct this, simply note that it is Function and not Block that is using the dollar sign to support a lexical scoping-like behavior. – Daniel Lichtblau Jul 19 '13 at 20:11