# Cycles

Hydroflow+ supports cyclic graphs, which are useful for iterative computations or patterns like heartbeats.

Because streams are represented as values when constructing a Hydroflow+ graph, we can't directly create cycles since that would require a forward reference. Instead, Hydroflow+ offers an API to create a cycle by using a *placeholder* stream, which is a stream that can be used as a placeholder for a stream that will be created later.

We can create a cycle by using the `cycle`

method on flow with a process or cluster. This returns a tuple of two values: a `HfCycle`

value that can be used to complete the cycle later and the placeholder stream.

`let (complete_cycle, cycle_placeholder) = flow.cycle(&process);`

For example, consider the classic graph reachability problem, which computes the nodes reachable from a given set of roots in a directed graph. This can be modeled as an iterative fixpoint computation where we start with the roots, then repeatedly add the children of each node to the set of reachable nodes until we reach a fixpoint.

In Hydroflow+, we can implement this using cycles:

`let roots = flow.source_stream(&process, roots);`

let edges = flow.source_stream(&process, edges);

let (complete_reached_nodes, reached_nodes) = flow.cycle(&process);

let reach_iteration = roots

.union(&reached_nodes)

.map(q!(|r| (r, ())))

.join(&edges)

.map(q!(|(_from, (_, to))| to));

complete_reached_nodes.complete(&reach_iteration);