Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

In C, one can have variables that are declared static. These are not re-initialized every single time a function is called. I.e.:

int f(int inc)
{
    static int x = 0;
    return x += inc;
}

Then f(0);f(1);f(2); will return 0,1, and 3. Is this possible in Mathematica?

One use that immediately comes to mind is having a compiled function stored as a static variable for use in a ME function.

share|improve this question
1  
Why not use global variables? If you afraid that other functions might change it, you can add Protect to its attributes and only unprotect it inside your Module. –  István Zachar Jan 13 at 18:08
3  
It looks like this is a duplicate of Modules that initialize themselves on first call –  rm -rf Jan 13 at 18:15
1  
See also the answer by @Leonid to What are the use cases for different scoping constructs –  Jens Jan 13 at 18:29
    
@Mark Providing another avenue to find solutions is exactly the role that duplicate questions play; if this one is closed it will still serve as a signpost to the original. –  Mr.Wizard Jan 13 at 19:09
    
@rm-rf Sort of - my question doesn't pertain to Module in particular however. –  VF1 Jan 13 at 20:43
show 6 more comments

2 Answers 2

up vote 8 down vote accepted

I use a context. I.e.:

f`x = 0;
f[inc_] := f`x += inc

f[0]
0

f[1]
1

f[2]
3

It is a global (though not in the Global context), using a namespace to protect it from inadvertent change.

You can also protect it inside a Module[]:

Module[{x},
 x = 0;
 f[inc_] := x += inc;
 ]

f[0]
0

f[1]
1

f[2]
3

It's still a global though:

?? f
Global`f
f[inc$_]:=x$274+=inc$

x$274
3

I don't know if there's a way to make a completely private, invisible static variable, like in C. I tried BeginPackage[], and it doesn't do anything magical either. Everything made in the package is accessible from outside.

This is kind of an issue in my mind. If I distribute a package, users of the package can make use of internal states that I do not intend to be used. If I distribute a new version with different internal states, it will break the code of those users. Yes, we can say that they were asking for it. However in other languages, this can be prevented entirely. Unless I've missed how to make invisible internal states in Mathematica.

share|improve this answer
    
I suppose if one really wants to mimic private scope then they would use Protect and Unprotect as István Zachar suggests. Also I think I'll use the context method instead of Module from now on because at least that global variable is clearly related to that function, whereas Module's temporary that is alive past its scope sort of looks messy and seems more prone to error. –  VF1 Jan 13 at 20:50
    
That's half of what private should mean. The other half is not being able to see or get the value of the private variable. –  Mark Adler Jan 13 at 20:54
    
Right, but that half is strictly related to aspects of programming design that are really more relevant to languages that have the static keyword. For Mathematica I suppose that the purpose of private is that of safety mainly. –  VF1 Jan 13 at 20:56
add comment

I think that there is at least one workaround, but it would be nice to see if anyone else has thought of anything. I got this answer from playing around with celtschk's answer to one of my OOP in MMA questions.

Module[{generator},
 generator[] :=
  Module[{field = 0},
    (* Function goes here, should be pure *)
    field += # &];
 increasing = generator[];
 ]

Evaluating this definition resets the "static" variable in increasing.

increasing[0]
(* 0 *)
increasing[1]
(* 1 *)
increasing[2]
(* 3 *)
share|improve this answer
    
@Nasser right, and since it's just a function (of which there should only ever be one instance, the generator is temporary and the object name is global. But for this specific purpose I think Mark Adler's way has better style (and avoids temporaries). –  VF1 Jan 13 at 23:28
add comment

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.