Tell me more ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I use a lot of functions that extract a specific data item from a file with many data items. I want these functions to load data (slow) and return the item (fast) on first call, but just return the item on subsequent calls. If I were using VB, I would declare static variables init along with other variables to hold the data, load the data and set init True on first call, and bypass the data load with an If init <> true then xxxx endif portion of the function on subsequent calls.

But variables listed within the {} of a Module don't persist from call to call. My workaround is to give the data an absurdly long variable name and exclude it from the the Module[{var1,var2,...} list, and use ValueQ to check if longvariablename has been evaluated. For example:

getPce[date_,column_] := Module[{dates, value, b, e},
   If[! ValueQ[longvariablename], longvariablename = Import["path\\file];
    value = SomeFunction[date_,column_]; (* get item(s) from longvariablename *) 
]

This is a clumsy. I'm sure there is a nice Mathematica way to do this, but I've never been able to figure it out.

share|improve this question
I've also struggled with this issue myself with Mathematica, untill I learned from the experts here and else where that one can use internal Modules to emulate a container object which is commonly used in object based languages. So now I use this method all the time. I've writte a small note to explain this method more, here is the link 12000.org/my_notes/object_based_in_mathematica/v1.html so I keep all the object own data inside the object and do not have to pass everything in and out as I had to do before. This is sort of like a Class. It has a constructor also.... – Nasser Oct 7 '12 at 15:24
... this helps alot in Mathematica becuase Mathematica does not have a 'struct' where one can store all the funtion parameters into one parameter like with say C/C++. Hence, before I had to pass many parameters to the function in each call, and returns them back. i.e. the caller was in charge of keeping track of all the data in its space. With this container method, each object stores its own data. This leads to much clear design. I really thing OO is the most natural way to write software (for me at least). But luckly one in Mathematica can emulate OO to some extent using internal modules. – Nasser Oct 7 '12 at 15:29

1 Answer

up vote 10 down vote accepted

You just have to wrap the Module around those variables, to make them semi-local:

Module[{persistent},
   persistent := persistent = Import["path\\file"];
   SomeFunction[date_,column_]:=
      (body using persistent);
   getPce[date_,column_] := 
      Module[{dates, value, b, e},              
          value = SomeFunction[...];   
      ]
]

Here we basically used Module to create a persistent variable, a method I mentioned here and described in more detail in my third post in this Mathgroup thread. We also used memoization to remember the value in subsequent calls. Another example of a very similar use of memoization is in definePartAPI function from this answer, with the only difference that I used there Unique to create the persistent symbol, instead of Module.

share|improve this answer
I'll try this, and thank you. But, would you say you are using memoization to make up for a scoping problem within MMa? Or is that just the wrong way to think about the problem? (I haven't read your links yet) – George Wolfe Oct 6 '12 at 16:44
@GeorgeWolfe No,these are 2 components of the solution: scoping serves to create a persistent variable, and memoization serves to remember the value for subsequent calls. They are independent. – Leonid Shifrin Oct 6 '12 at 16:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.