MathGroup Archive 2007

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

Search the Archive

Re: removing those annoying $$$$'s from local variables names?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg79719] Re: removing those annoying $$$$'s from local variables names?
  • From: Albert <awnl at arcor.net>
  • Date: Thu, 2 Aug 2007 03:58:37 -0400 (EDT)
  • References: <f8pk78$2i1$1@smc.vnet.net>

Hi,

> This problem is when a function returns back a symbol which is local
> to the function, 

> This is an example:
> 
> ------------- example 1 -------------
> 
> foo[] := Module[{c, k},
>               c = Array[k, 3]
>           ];
> 
> c = foo[];
> Print[c];
> 
> {k$76[1], k$76[2], k$76[3]}
> --------------------------------------------------
> 
> You see, since k is local to foo[], then when I print it, I see those $
> $$ signs.

to be precise the symbols are not local to the function foo but to the 
Module...

> Only way to remove this $$$'s is to make k global as follows

Be sure that there are another 1000 ways to "remove" them :-)

> ------------------------ example 2 -------------------
> Remove[k];
> foo[] := Module[{c},
>               c = Array[k, 3]
>           ];
> 
> c = foo[];
> Print[c];
> 
> {k[1], k[2], k[3]}
> ----------------------------------------
> 
> But making 'k' global is something I do NOT want to do, since now I
> have to worry about 'k' having a value somewhere else in the code, and
> it goes against the whole idea of encapsulation.

Honestly, I think returning expressions that contain these local symbols 
is against the whole idea of encapsulation in the first place...

> If I start making all
> my symbols global, then the code becomes hard to manage.

very true, you should absolutely use local variables as much as possible...

> So, what should one do in this case?  How can make all the symbols
> local to a function, but at the same time not see these $$$'s when the
> symbols are used when they are returned from the function back to the
> caller?

the problem you have is that when returning "local" symbols they need to 
have different names than the possibly existing globals, otherwise there 
is nor chance to separate them once you leave the Module. Try to use 
Block instead of Module and you will see that localization does not make 
sense (unless you want the special behaviour of the following code) when 
returning the local symbols with names that already exist as globals:

In[32]:= k = 15
Block[{k, a}, a = Array[k, 3]; Print[a]; a]


Out[32]= 15

(* the follwing is the result of the Print *)
During evaluation of In[32]:= {k[1], k[2], k[3]}

Out[33]= {15[1], 15[2], 15[3]}

One thing you can do is to only make the local symbols look simpler in 
output but still have the names, like this:

In[34]:= res = Module[{k}, Format[k] = "k";
   Array[k, 3]]
Out[34]= {"k"[1], "k"[2], "k"[3]}

you won't see the "" in the notebook interface with default settings. 
But note that:

In[35]:= InputForm[res]
Out[35]//InputForm=
{k$444[1], k$444[2], k$444[3]}

so something like:

res/.k->kk

will not work. If all that happens to the returned expression is 
printing this might solve your issue. If that is the case and k is just 
used as a label, you could return an expression with strings in the 
first place, which is rather simple and robust (and makes the Module 
superfluous, by the way):

Module[{},Array["k",3]]

It is not entirely clear to me what you want to do and if these are 
reasonable "solutions" to your problem. After all it is quite obscure to 
most users when these k's are now different than there representation or 
are strings and not symbols. Maybe it would be a good idea if you'd 
explain what you want to achieve. I can hardly believe that there are 
not better methods to do what you probably want than to return those 
local symbols as output. One thing that I often do is to return a 
function object rather than an expression, which solves the problem of 
"which kind of symbol should be in that expression" quite neatly:

In[30]:= res = Module[{k}, Function @@ {{k}, Array[k, 3]}]

Out[30]= Function[{k$440}, {k$440[1], k$440[2], k$440[3]}]

Note that I needed to use a trick to enforce evaluation of the function 
body and avoid additional scoping by Function...

Now in the calling code you can choose what the name of the symbol in 
the returned expression should be (and e.g. use symbol which is local in 
the calling module), like in:

In[31]:= res[myk]

Out[31]= {myk[1], myk[2], myk[3]}

or for pretty printing even insert a string:

Print[res["k"]]

{"k"[1], "k"[2], "k"[3]}

Another option is to use an additional argument so that again the 
calling code can define which symbol should be used:

foo[sym_]:=Array[sym,3]

foo[k]



hth,

albert


  • Prev by Date: Density Plot coloring issue
  • Next by Date: Re: Numerical integration
  • Previous by thread: Re: removing those annoying $$$$'s from local variables names?
  • Next by thread: Re: Setting and Unsetting values, memory usage problems.