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.

查看推荐产品

Comments powered by Disqus