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