Mathematica 9 is now available
Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: function local/private to another function?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg110599] Re: function local/private to another function?
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Sun, 27 Jun 2010 04:56:28 -0400 (EDT)

Hi Nasser,


> What is the best way to have a function which can only be "seen" and
> called by only the enclosing parent function? And not be in the global
> space (without using a package?).
>
> You first guess is right on target:

f1[x_]:=Module[{b,f2},
    ....
    f2[y_]:=Module[{c},...c=y^2...
>
> Return[x]];
>     b=f2[x]
>     ...
> ]



does exactly what you want. <c> is indeed local to <f2> and not to <f1>.
Moreover, you can use some of the variables local to <f1> inside <f2>, then
<f2> will become what is usually called a closure - a function that grabs
its surrounding environment, a very useful thing. One of the many reasons to
use it is that you can return it from the external Module, and it will keep
track of the environment surrounding it at the time of its creation long
after that environment itself is gone (we exit external Module). This allows
new ways of organizing the code, since you get a light-weight and cheap
state encapsulation without the rest of the OOP boilerplate and associated
with it tedium.

If you do use some of the local variables of <f1> directly in <f2>, you can
also do it in two different ways: using their names directly (and then your
f2 will be able to change the original variables in the future), or
embedding their values using With[{myvar = ...},f2[...]:=...], in which case
you embed an immutable screenshot of the surrounding environment. Depending
on the situation, you may find that you need the first or the second method.


Regarding   your puzzlement with

f1[x_]:=Module[{c,f2},
    ....
    f2[y_]:=Module[{c},...];

This happens because naming local variables the same way causes the name
conflict in nested scoping constructs. In most cases (including this one),
such conflicts do not represent the error per se, but rather the warning
that the variable binding is subject to certain name conflict resolution
rules and may be not what you may expect in some cases. Again, in most cases
(including this one) such conflicts  are resolved in favor of the inner
scoping construct, so for example:

f1[x_] :=
  Module[{c = 2, f2},
   f2[y_] :=
    Module[{c = 1}, Print[c]];
   f2[1]
   ];

f1[3]

1

For your use case, then, it will work correctly, if you can live with the
annoying red coloring - otherwise just use different names for variables.

I Wanted to find what is the best way to have a local function, with its
> own local variables inside a parent function, where the only interaction
> between the inner function and the parent function is via the argument
> call. I looked at Block and With, but they do not do what I need.



Regarding Block and With, you are right that they won't help you to make a
local DownValues (OwnValues,UpValues, SubValues,etc)  - based
pattern-defined function - you really need to create a new symbol with a
local lexical scope for the name of your function, and this is exactly what
Module does. Block and With OTOH do not create new symbols.

With Block, you will have a local function in a way, but for the price that
the original symbol with the same name is shadowed and can not be referenced
within the scope of Block, which is dynamic, so we are talking about the
part of the execution stack - the scope of Block is in time rather than in
space, in a way. This is often useful, but under different circumstances,
and will give not what you probably had in mind.


> I
> think Module is the only choice left?  Or should I not bother about
> having local functions to another functions at all and leave everything
> in the global space?
>
>
Well, you can use Unique to simulate lexical scoping yourself, but Module
has several advantages (two major ones IMO being automatic name conflicts
resolution and automatic garbage collection of local symbols which are not
referenced outside of the defining Module scope), so I would go with Module
- this is a good way I think ( I use this all the time anyway) . Yet another
way is to use pure functions, which you can assign to local variables. For
example:

Clear[f1];
f1[x_] :=
  Module[{c = 2, f2 = Function[y, Module[{c = 1}, Print[c + y]]]},
   f2[x]];

f1[3]
4

In such a construct, With could be used instead of external Module with the
similar effect. Of course, such local functions will have all the
limitations of the pure functions (no pattern-based definitions, no easy
argument checks, no multiple definitions).

Generally, I recommend you to follow this thread:

http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/5eff6213a0ab5f51/29f3c90fe11b4926

particularly, my third post there, where I discuss these sort of constructs
rather extensively and give references to a few more threads on similar
topics that I am aware of.

Hope this helps.

Regards,
Leonid

--0015174482ce4c27790489f12b41
Content-Type: text/html; charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable
X-Sun-Content-Length: 6084

Hi Nasser,<br><div class="gmail_quote"><br><blockquote class="gmail_quo=
te" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt=
 0.8ex; padding-left: 1ex;">
<br>
What is the best way to have a function which can only be &quot;seen&quot; =
and<br>
called by only the enclosing parent function? And not be in the global<br>
space (without using a package?).<br>
<br>
</blockquote><div>You first guess is right on target: <br>
<br>
f1[x_]:=Module[{b,f2},<br>

     ....<br>

     f2[y_]:=Module[{c},...c=y^2...
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, =
204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Return[x]];<br>
     b=f2[x]<br>
     ...<br>
]</blockquote><div> </div>
<br>
does exactly what you want. &lt;c&gt; is indeed local to &lt;f2&gt; and
not to &lt;f1&gt;. Moreover, you can use some of the variables local to
&lt;f1&gt; inside &lt;f2&gt;, then &lt;f2&gt; will become what is
usually called a closure - a function that grabs its surrounding
environment, a very useful thing. One of the many reasons to use it is that=
 you can return it from the external Module, and it will keep track of the =
environment surrounding it at the time of its creation long after that envi=
ronment itself is gone (we exit external Module). This allows new ways of o=
rganizing the code, since you get a light-weight and cheap state encapsulat=
ion without the rest of the OOP boilerplate and associated with it tedium. =
<br>
<br>If you do use some of the local variables of &lt;f1&gt; directly in &lt=
;f2&gt;, you can also do it in two different ways: using their names direct=
ly (and then your f2 will be able to change the original variables in the f=
uture), or embedding their values using With[{myvar = ...},f2[...]:=...=
], in which case you embed an immutable screenshot of the surrounding envir=
onment. Depending on the situation, you may find that you need the first or=
 the second method. <br>

<br>
Regarding   your puzzlement with <br>
<br>
f1[x_]:=Module[{c,f2},<br>

     ....<br>

     f2[y_]:=Module[{c},...];<br>
<br>
This happens because naming local variables the same way causes the
name conflict in nested scoping constructs. In most cases (including
this one), such conflicts do not represent the error per se, but rather the=
 warning that the variable binding is subject to certain name conflict reso=
lution rules and may be not what you may expect in some cases. Again, in mo=
st cases (including
this one) such conflicts  are resolved in favor of the inner scoping
construct, so for example:<br>
<br>
f1[x_] :=<br>
  Module[{c = 2, f2},<br>
   f2[y_] :=<br>
    Module[{c = 1}, Print[c]];<br>
   f2[1]<br>
   ];<br>
<br>
f1[3]<br>
<br>
1<br>
<br>
For your use case, then, it will work correctly, if you can live with
the annoying red coloring - otherwise just use different names for
variables. 
<br><br></div><blockquote class="gmail_quote" style="border-left: 1px s=
olid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I Wanted to find what is the best way to have a local function, with its<br=
>
own local variables inside a parent function, where the only interaction<br=
>
between the inner function and the parent function is via the argument<br>
call. I looked at Block and With, but they do not do what I need. </blockqu=
ote><br><div><br>Regarding Block and With, you are right that they won&#39;=
t help you
to make a local DownValues (OwnValues,UpValues, SubValues,etc)  - based p=
attern-defined function - you really need to create a new symbol with
a local lexical scope for the name of your function, and this is exactly wh=
at Module does. Block and
With OTOH do not create new symbols. <br><br>With Block, you will have a lo=
cal function in a way, but for the price that the original symbol with the =
same name is shadowed and can not be referenced within the scope of Block, =
which is dynamic, so we are talking about the part of the execution stack -=
 the scope of Block is in time rather than in space, in a way. This is ofte=
n useful, but under different circumstances, and will give not what you pro=
bably had in mind.<br>
 </div><blockquote class="gmail_quote" style="border-left: 1px solid =
rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">I<br>
think Module is the only choice left?  Or should I not bother about<br>
having local functions to another functions at all and leave everything<br>
in the global space?<br>
<br></blockquote><div><br>Well, you can use Unique to simulate lexical scop=
ing yourself, but Module has several advantages (two major ones IMO being a=
utomatic name conflicts resolution and automatic garbage collection of loca=
l symbols which are not referenced outside of the defining Module scope), s=
o I would go with Module - this is a good way I think ( I use this all the =
time anyway) . Yet another way is to use pure functions, which you can assi=
gn to local variables. For example:<br>
<br>Clear[f1];<br>f1[x_] :=<br>  Module[{c = 2, f2 = Function[y, Mo=
dule[{c = 1}, Print[c + y]]]},<br>   f2[x]];<br><br>f1[3]<br>4<br><br=
>In such a construct, With could be used instead of external Module with th=
e similar effect. Of course, such local functions will have all the limitat=
ions of the pure functions (no pattern-based definitions, no easy argument =
checks, no multiple definitions).<br>
<br>Generally, I recommend you to follow this thread:<br><br><a href="htt=
p://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/th=
read/5eff6213a0ab5f51/29f3c90fe11b4926">http://groups.google.com/group/comp=
.soft-sys.math.mathematica/browse_thread/thread/5eff6213a0ab5f51/29f3c90fe1=
1b4926</a><br>
<br>particularly, my third post there, where I discuss these sort of constr=
ucts rather extensively and give references to a few more threads on simila=
r topics that I am aware of.<br><br>Hope this helps.<br><br>Regards,<br>
Leonid<br><br> </div></div><br>

--0015174482ce4c27790489f12b41--


  • Prev by Date: Re: Creating sub-list based on a given criterion
  • Next by Date: Re: Why?
  • Previous by thread: function local/private to another function?
  • Next by thread: Particle Filters