What I've observed in the Java version, is that the ranks can change during a transaction, which leads to all entries being removed then reinserted into the priority queue to keep updates occurring in the correct order.
This is really needed just for
StreamLoop, because you do not know what the rank is ment to be until the call to
Another thing about ranks is that they are not allowed to cycle. However references to sodium objects are allowed to cycle.
StreamLoop<Integer> sl = new StreamLoop<>();
Stream<Integer> sOut = sl.map(x -> x + 1);
Has a rank-cycle, and is not allowed as its rank will spiral up to infinity. (not an infinite loop currently because there is a
visited set in the code to stop that)
So how about ranks as Expressions, rather than Integers. So that a rank-cycle can be detected at run-time and an Exception can be thrown. Also ranks as Expressions can be evaluated late when the rank is really needed, so that the priority queue does not need to be cleared then refilled.
= RE_Max RankExp RankExp
| RE_Plus RankExp Int
| RE_Const Int
| RE_Var Ident
RE_Var gets used to point to a rank which might not yet be known, and can be obtained later. Such as
loop is called.
I know what Java does at the moment works, and "If it ain't broken, why fix it?". But just seems like it could be done a little cleaner.
On second thought a memoized lazy integer for the rank would do too. And simply throw an Exception if the rank is evaluated too soon.