Parameter passing "feature" is correct!

*To*: mathgroup at yoda.ncsa.uiuc.edu*Subject*: Parameter passing "feature" is correct!*From*: CAMERON at midd.cc.middlebury.edu*Date*: Sun, 14 Oct 90 15:02 EDT

David Jacobson writes: > When a function has the HoldAll (or HoldFirst or HoldRest) attributes, > there are possible name conflicts between symbols in actual parameters > (arguments) and local variable declared in blocks... Quite true. Mathematica's evaluation strategy is (at least 80% of the time) pure textual substitution and term-rewriting. In the example below, "foo[z]" causes the pattern variable "x" to match the "z" (which is not rewritten because of the "HoldAll" attribute). The MEANING of the ":=" is that whatever is matched by the pattern variables on the left-hand side is substituted for those variables on the right-hand side. Thus "foo[z]" is rewritten to "{Block[{z=3},z],z}". After that rewriting happens, "foo" (and its "HoldAll" attribute) are no longer part of the expression, so further rewriting can now happen. The first element of the list has "z" inside a Block in which "z" has the value 3, so that "z" rewrites to 3 (this rewriting is what it MEANS in Mathematica for "z" to "have the value 3"). The second element is not inside a block, so the "z" there gets rewritten according to the global rules, which give "z" the value 1. > I'm not sure this is a bug, ... It's not. I suppose you could claim that it's a "design misfeature", but Mathematica IS DOING what it's documented to do. This is why there are "Contexts" in the language. Compare the behavior of "foo" to that of "bar" below. Once again the "z" in "bar[z]" is not rewritten immediately because of a "HoldAll" attribute. But this time "bar[z]" gets rewritten to "{Block[{Private`z=3},{z,Private`z}],{z,Private`z}}". Now a "z" in the context "Private`" is NOT the same symbol as a "z" in the (default) context "Global`", so the rule on "Private`z" inside the Block does not affect the "z" that was passed in as the argument to "bar". The result is that of the two distinct "z"'s inside the Block, the first one gets rewritten according to the rules for "Global`z", so it becomes a 1, while the second gets rewritten according to the rules for "Private`z", so it becomes a 3. The two "z"'s in the second sublist are in the scope of the global rules only, not inside a Block, so the first one ("Global`z") gets rewritten to 1 as before, but the second one ("Private`z") does not get rewritten at all, because the global rule base contains no rules for the symbol "Private`z". Of course, the usual way of putting symbols into a different context than "Global`" is not to write the fully-qualified names with explicit context prefixes, but to use "Begin[]" or "BeginPackage[]" to tell the parser to use a different context as default until the corresponding "End[]" or "EndPackage[]". The parser interprets symbol names not explicitly qualified by a context prefix as belonging to the context named by the current value of "$Context", which is affected by "Begin[]", "BeginPackage[]", "End[]", and "EndPackage[]". In[1]:= SetAttributes[foo, HoldAll] In[2]:= foo[x_] := { Block[{z=3},x], x } In[3]:= foo[1] Out[3]= {1, 1} In[4]:= z=1; foo[z] Out[4]= {3, 1} In[5]:= SetAttributes[bar, HoldAll] In[6]:= bar[x_] := { Block[{Private`z=3}, {x,Private`z} ], {x,Private`z} } In[7]:= z Out[7]= 1 In[8]:= bar[z] Out[8]= {{1, 3}, {1, Private`z}} In[9]:= bar[1] Out[9]= {{1, 3}, {1, Private`z}} I hope this explanation causes more understanding than confusion! --Cameron Smith Mathematica programming consultant CAMERON at MIDD.BITNET --or-- cameron at midd.cc.middlebury.edu

**Mathematica Conference attendance**

**Mathematica Conference**

**Mathematica Conference attendance**

**Mathematica Conference**