Re: Functions, Part 1
- To: mathgroup at christensen.cybernetics.net
- Subject: [mg569] Re: [mg564] Functions, Part 1
- From: villegas (Robert Villegas)
- Date: Sun, 19 Mar 1995 04:01:24 -0600
> (1) f[x_] := x + 1 > > (2) g = Function[x,f[x]] > > (3) h = Function[x,Function[y,y+1]] > > Now g[2] and f[2] output 3 as expected. But > h[2] (indeed, h[garbage]) outputs Function[y,y+1]. What`s going on? > > Clearly, I do not understand exactly what happens when one > uses the notation Function[x,body][2] since what I thought happens > was this: Every appearance of x in the expression "body" is > replaced by 2 and then body is evaluated. In view of (3) this > surely is not what happens. Or am I way off base? Hello Jack, Your understanding of Function is essentially correct. And in your (3), there is no x anywhere in the body, just y, so I think the result fits your mental model just fine. I'm not sure what you were expecting... did you mean to use a slightly different example, like this? (4) h = Function[x, Function[x, x + 1]] If so, then I could see some confusion arising from the results: In[5]:= h = Function[x, Function[x, x + 1]] Out[5]= Function[x, Function[x, x + 1]] In[6]:= h[3] Out[6]= Function[x, x + 1] You might expect the 3 to be substituted for every occurrence of x, no matter where it was, which would yield Function[3, 3 + 1] (which, by the way, would return an error because 3 isn't a valid variable). But the 3 isn't substituted for x inside the inner Function because the inner Function "owns" its own x, and the outer Function keeps its hands off. In fact, it is a rule of thumb for scoping constructs like Function, With, and Module that when you nest them and they both use a symbol, say x, as a local variable, the outer one won't substitute anything for x in the inner one. Here's another example similar to yours, but using With. The inner With is kept frozen so we can see exactly how the outer one affected (or rather, didn't affect) it. In[8]:= With[{x = a}, HoldForm @ With[{x = 1}, x + a] ] Out[8]= With[{x = 1}, x + a] If the outer one had infringed on the x of the inner one, we would have gotten back With[{a = 1}, a + a] instead, but we didn't. That rule of thumb about a "non-interference" policy for nested scoping constructs isn't the full story, because assignments and rules (SetDelayed and RuleDelayed) are scoping constructs, but they do not respect inner scoping constructs (including each other) when they substitute. These things are given respect by other things when they are nested, but they do not respect things nested in them. A different issue is renaming of local variables (I posted a couple notes about this a while back). If you want to know more of the story, I'd be glad to give you a more thorough discussion of it, or refer you to people intimately familiar with the internal code if needed. Best regards, Robby Villegas