As was pointed out in a recent post scoping does not work as expected inside of Module.
An example from that thread is:
Module[{expr},
expr = 2 z;
f[z_] = expr;
f[7]]
(*2 z*)
But the following works almost as expected.
Module[{expr},
expr = 2 z;
Set@@{f[z_], expr};
f[7]]
(*14*)
What language design consideration made wolfram choose this functionality?
Edit: See Jefromi's first comment I changed z from being a local variable to not and forgot to change the output. It does not effect the problem.
Edit2: Michael Pilat's point seems to be that Block and Module have different functions. I think I understand his point, but I think that it is orthogonal to my question. So here is an update.
I can use the following code at the the global level in a notebook:
expr = 2 z;
f[z_] = expr;
f[7]
(*output: 14*)
But when I put the same code block into a Module and make expr local it produces a different output.
Clear[f];
Module[{expr},
expr = 2 z;
f[z_] = expr;
f[7]]
(*output: 2z*)
If you trace the above Module call you find that Set[f[z_], expr] is rewritten to Set[f[z$_,expr]. Now this z->z$ transformation happens on both the lhs and rhs of the Set. It however happens before expr is evaluated, which causes a different result then would be obtained at the global level.
The transformation z->z$ only seems to happen when the rhs has a symbol local to the Module call.
Why does Mathematica choose to have this syntax change in a Module call? What language/implementation design tradeoffs exist here that made this decision.