Expanding recursive calls eagerly will lead to OutOfMemoryError.
It is currently not common because
recursive calls are usually in a conditional branch (|+| or |&|); and
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:
The frontier is impermeable to a propagating crash (just like to any other in-flow).
However, cancellation should propagate, but expand only as much as necessary.
If the activation Ping signal crashes, the whole frontier crashes/cancels.
Problem
Expanding recursive calls eagerly will lead to
OutOfMemoryError
.It is currently not common because
|+|
or|&|
); andHowever, 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.
Care needs to be taken around crash and cancellation of unexpanded functions:
Ping
signal crashes, the whole frontier crashes/cancels.