Closures in Modelica
Modelica supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.
function intSeq
output Function nextInt;
protected
Integer i(start=0);
algorithm
nextInt := function
output Integer out;
algorithm
i := i + 1;
out := i;
end function;
end intSeq;
function main
protected
Function nextInt;
Function newInts;
algorithm
nextInt := intSeq();
Modelica.Utilities.Streams.print(String(nextInt()));
Modelica.Utilities.Streams.print(String(nextInt()));
Modelica.Utilities.Streams.print(String(nextInt()));
newInts := intSeq();
Modelica.Utilities.Streams.print(String(newInts()));
end main;
This function intSeq
returns another function, which we define anonymously in the body of intSeq
. The returned function closes over the variable i
to form a closure.
In the main
function, we call intSeq
, assigning the result (a function) to nextInt
. This function value captures its own i
value, which will be updated each time we call nextInt
.
We can see the effect of the closure by calling nextInt
a few times.
To confirm that the state is unique to that particular function, we create and test a new one.
To run this Modelica code, you would typically use a Modelica simulation environment. The output would be:
1
2
3
1
Note that Modelica is primarily used for modeling and simulation of physical systems, so this example is somewhat atypical. In a real-world scenario, you might use closures in Modelica for more domain-specific purposes, such as defining custom components or equations that maintain internal state.
The next feature we’ll look at is recursion, which is also supported in Modelica.