Re: Re: functions inside Module
- To: mathgroup at smc.vnet.net
- Subject: [mg38379] Re: [mg38343] Re: [mg38234] functions inside Module
- From: Alexander Sauer-Budge <ambudge at MIT.EDU>
- Date: Fri, 13 Dec 2002 04:09:43 -0500 (EST)
- Sender: owner-wri-mathgroup at wolfram.com
Gianluca ,
First, symbol names declared in a module, like 'h' below, are
"silently" renamed to avoid conflict with the parent scope. Second, a
pattern identifier for a function defined in a module is not considered
to be the same as a declared symbol of the same "name."
Very loosely, Mathematica interprets
> Module[{num, x, den, h},
> num = x^2;
> den = 1 + x^2;
> h[x_] = num/den;
> h'[1]]
as
Module[{},
num$ = x$^2;
den$ = 1 + x$^2;
h[x_] = num$/den$;
h'[1]]
so that the pattern symbol x in the definition of h does not actually
occur in the right hand side, since x$ occurs there instead.
The solution is not to use so called free variables, but to bind
symbols more tightly to there expressions, like in the following example
Module[{h},
h[x_] = With[{num = x^2, den = 1+x^2}, num/den];
h'[1]]
Of course, for this simple example you probably would rather just write
Function[x, x^2/(1+x^2)]'[1]
and avoid the module altogether.
Cheers!
Alex
On Thursday, December 12, 2002, at 01:36 AM, Gianluca Gorni wrote:
>
> Thank you for your reply. I am sorry that my understanding
> of scoping is so poor.
>
> My rule-of-thumb for making Module[] was to start off without
> local variables, for example:
>
> Module[{},
> num = x^2;
> den = 1 + x^2;
> h[x_] = num/den;
> h'[1]]
>
> so that I can debug easily. When I finally get it to work
> I add the list of the local variables:
>
> Module[{num, x, den, h},
> num = x^2;
> den = 1 + x^2;
> h[x_] = num/den;
> h'[1]]
>
> But now it is broken!
>
> I wish to be enlightened on this issue: How can I safely
> write a function definition inside a Module?
>
> Gianluca Gorni
>
>> From: David Withoff <withoff at wolfram.com>
To: mathgroup at smc.vnet.net
> To: mathgroup at smc.vnet.net
>> Date: Tue, 10 Dec 2002 15:02:17 -0600
>> To: gorni at dimi.uniud.it
>> Subject: [mg38379] [mg38343] Re: [mg38234] functions inside Module
>>
>>> I am confused by this result:
>>>
>>> In: Module[{a}, a = x; g[x_] = a]; g[y]
>>>
>>> Out: x
>>>
>>> Somehow I would expect the same output as
>>>
>>> In: Module[{}, a = x; g[x_] = a]; g[y]
>>>
>>> Out: y
>>>
>>> In the first case ?g gives g[x$_] = x,
>>> while in the second it gives g[x_] = x.
>>> The difference is a dollar sign.
>>>
>>> Can anyone explain why the dollar is inserted in one case
>>> but not in the other? The x was not a local variable
>>> in either case.
>>
>> Since the names of named patterns in rules and definitions
>> are treated as local variables, the x in the definition of
>> g[x_] is a local variable in these examples (section 2.6.4
>> in The Mathematica Book). Module[{a}, a = x; g[x_] = a]
>> therefore contains nested scoping constructs, so the local
>> symbol x in g[x_] = a is renamed to prevent a potential
>> conflict with the variable a from the enclosing Module.
>>
>> In Module[{}, a = x; g[x_] = a], where there are no conflicting
>> variables from the nested scoping constructs, the definition of
>> g is evaluated as if the Module was not present. Since this
>> definition is an immediate assignment, the right side of the
>> assignment is not held unevaluated, and will be affected by
>> definitions (such as the now global definition of a) that are
>> present when the assignment is evaluated.
>>
>> If you use a delayed assignment for the definition of g
>> then both inputs will show the same result:
>>
>> In[1]:= Module[{a},a=x;g[x_]:=a];g[y]
>>
>> Out[1]= x
>>
>> In[2]:= Module[{},a=x;g[x_]:=a];g[y]
>>
>> Out[2]= x
>>
>> The only fundamentally troublesome issue here is that immediate
>> assignments are treated as scoping constructs even though they
>> do not hold their arguments unevaluated.
>
>