TomasMikula / libretto

Declarative concurrency and stream processing library for Scala
Mozilla Public License 2.0
196 stars 7 forks source link

Controlled expansion of recursive calls #68

Open TomasMikula opened 2 years ago

TomasMikula commented 2 years ago

Problem

Expanding recursive calls eagerly will lead to OutOfMemoryError.

It is currently not common because

  1. recursive calls are usually in a conditional branch (|+| or |&|); and
  2. we expand only the branch that will be executed, and thus delay the expansion until the branch is known.

However, there are useful (infinite) programs that have an unconditional recursive call. Although the recursive instance of a function might stay inactive until input flows into it, expanding the function eagerly leads to OutOfMemoryError.

TODO: provide an example

Proposed solution

Introduce a recursion operator that keeps recursive calls unexpanded (and thus also inactive) until an activation signal is received.

def controlledRec[A, B](((Ping |*| A) -⚬ B) => (A -⚬ B)): A -⚬ B

Care needs to be taken around crash and cancellation of unexpanded functions: