2

Ok, sorry if this is too basic, I'm somewhat new to Mathematica, but I keep making errors in my code because I'm not understanding the namespaces.

So this part I thought I understood.

x = y;
f[y_] := x;
g[yval_] := y = yval; x;
f[1]  ---> y
g[1]  ---> 1

Using y as a name for a function argument doesn't change the value of y in the global namespace, or so I thought. So there's some place, when I call f, that the association y = 1 is stored, but not in the global namespace like if I actually run y = 1. And that's why x is staying the same.

But then I encountered this.

h[y_] := Global`y;
h[1]  ---> 1
k[y_] := Global`y = y; x;
k[1]  ---> Set: Cannot assign to raw object 1. (1 = 1 is throwing the error.)

So I don't understand: Set[y,1] is doing something differently from the pattern argument, but they're both changing y in the global namespace. So what is Set doing that's different? It seems like Set[y,1] changes, say, {x -> y, y -> 7} to {x -> 1, y -> 1}, while the pattern just changes {x -> y, y -> 7} to {x -> y, y -> 1}.

Is this the right idea? Does Set go through and find everything that depends on y and change it too? Could I replicate that behavior inside a function where y is an argument? (Not that I'd want to, that would be an abomination.) If I try to run y = y, I get an error. Is there some way to refer to "all the other y's" and Set them?

Anyway, I'd just really appreciate a better understanding of what's going on here. Thanks!

NathanRL
  • 127
  • 6

1 Answers1

3

I don't follow your last question "Is there some way to refer to 'all the other y's' and Set them?" but I think I can get to the heart of the matter.

The substitution of argument values into matching Pattern Symbols on the right hand side of a function definition does not work by means of assignment but rather replacement. See Expressions containing globally undefined symbols inside a function where they are defined and linked questions for other ramifications of this.

So in effect k[1] evaluates somewhat like:

Replace[Unevaluated[y = y], HoldPattern[y] :> 1, {-1}]

Set::setraw: Cannot assign to raw object 1. >>

1

Observe this behavior; if this relied on evaluation of x the value 7 would not appear:

foo[x_] := HoldComplete[x]

foo[7]

HoldComplete[7]

By the way your use of Global` is largely superfluous in this example as that is the default context.

Also you have a line:

k[y_] := Global`y = y; x;

I do not know what purpose x; is supposed to serve, but this is not part of the SetDelayed definition on k as CompoundExpression has a lower precedence:

Precedence /@ {SetDelayed, CompoundExpression}
{40., 10.}
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371