Re: Returning a local array

*To*: mathgroup at smc.vnet.net*Subject*: [mg84279] Re: Returning a local array*From*: Albert Retey <awnl at arcor.net>*Date*: Mon, 17 Dec 2007 19:14:00 -0500 (EST)*References*: <fjqj9l$6l9$1@smc.vnet.net> <fjr2ra$53j$1@smc.vnet.net> <fjtrik$d00$1@smc.vnet.net>

Hi, > > For the purely practical reason that ?g display all values for the > array. If g is a reference to the local variable, these values are not > displayed. > > I would be surprised if the local variable is not garbage collected > when dereferenced. Is there really a 'memory leak' in this case? I think you are right, the local symbols of Module when returned have the attribute Temporary which controls that. >> Another thing you could do is to supply the symbol as an argument like: >> >> f[v_]:=(v["a"]=1;v["b"]=2;v) >> >> and then use: >> >> f[g] >> >> If you don't like the syntax, you can make that approach look like the >> other by using UpValues: >> >> f/:(v_=f[]):=(v["a"]=1;v["b"]=2;v) >> > > Thanks, I used your first suggestion in addition to SetAttributed[f, > HoldFirst] as Jens-Peer suggested. I am assuming this is how functions > such as AppendTo work. Usually if you work with a symbol rather than with it's value as we do here it is a good idea to use the hold attribute, so the advice from Jens-Peer in general is valid. On the other hand it doesn't make a big difference here since we work with the downvalues only and if there is an own value set, neither will the above code work nor would it be possible to access the downvalues since the head will be evaluated first. The code could be made more "robust" by clearing all definitions of g before setting the downvalues, and then the hold attribute would make sense: SetAttributes[f, HoldFirst] f[v_] := (ClearAll[v]; v["a"] = 1; v["b"] = 2; v) this should work even if you set, e.g.: g=6 f[g] but I'm not sure whether this is what you or a user of the function f would expect. >>> Is it better to work with rules instead? It can become awkward and I >>> would like to avoid it. >>> f[] := Module[{h}, h={"a" -> 1, "b" -> 2}; h]; >>> g = f[]; >>> "a" /. g >> This is probably a way which is more often seen in Mathematica code. >> Anyway there are counterexamples and your above strategy for "misusing" >> the pattern matcher to construct data structures is used elsewhere, too, >> and I think I have seen it used even within parts of Mathematica's own >> standard libraries... >> >> Note that you could also define a supporting function which makes the >> access look more familiar: >> >> get[rules_,attr_]:=attr/.rules; >> >> get[g,"a"] > > I looked at Maeder's Classes.m which is a more elaborate illustration > of how to do what you suggested. I don't see this kind of code used > very much. That's a good point, AFAIK there are no established best practices of how to handle "structured data", although the approach of lists of rules, usually with a specific head and in combination with access function has been suggested several times in this group, so I think people are using it. I have not yet seen anyone suggest the approach of using downvalues as in the above code although I see some advantages in it. cheers, albert