Generic Reactors
This article has examples in the following target languages:
- C
- C++
Generic Reactors​
Sometimes it is useful to implement a generic pattern without knowing the concrete types used. For instance, it could be useful to implement a delay reactor that forwards all values it receives with a fixed delay, regardless of their datatype. For this pattern, it is not required to know the concrete type in advance, and we would like to reuse the same logic for different types. This can be achieved with generic reactors in LF. Consider the following example:
The example above defines a generic reactor Delay
which has a type parameter named T
. Its input, output and logical action are all of type T
. The logic implemented in the reactions is straightforward. The reaction to in
schedules the logical action a
with the configured delay and the received value. The reaction to a
simply forwards this value to the output port at a later tag. The concrete type T
, however, is not relevant for this implementation and will be filled in only when the reactor is instantiated. In our example, the main reactor instantiates Delay
, specifying int
as the type to be assigned to T
. As a consequence, we can set an integer on d
's input port and receive an integer on its output. If we wanted instead to delay a string, we can do this as follows:
Reactor definitions may also specify multiple type parameters. Moreover, type parameters are not limited to ports and actions, but can also be used in state variables, parameters, or methods. For instance, we can define the following reactor:
This reactor could be instantiated for example like this: