issa-tseng / janus

the two-faced application library-framework.
http://janusjs.org
37 stars 7 forks source link

Maybe: delta-based data structure effect vending system #161

Open issa-tseng opened 5 years ago

issa-tseng commented 5 years ago

(this maybe applies to varying too actually but varying has solved this problem in a different way).

so despite the promise of janus, the reality is that time does exist. usually this doesn't matter because most side effects in practical janus code do not directly/synchronously generate further side effects. so while there may be some instability in system state while time propagates, it does quickly settle down.

however, there is one area that is susceptible to problems here: data structures, and especially List. we have three different sets of effect notifications to vend when a List is changed:

in general, lower level code uses events and higher level code uses transformation and reaction. so, a .mapped List internally uses the events, but you would likely do something like .get(-1) or similar to actually consume the mapped list.

the fact that we have all these different propagation systems (which for now seems somewhat unavoidable) leads to issues when they are used to trigger new propagations.

a simple example: someList.length.react(l => { if (l === 0) someList.add(defaultobj); }). janus vends effects in the order listed above, which leads to no problems with this code. if, however, events are vended after everything else, this reaction causes all the indices to line up incorrectly by the time events are propagated (unbeknownst to that synchronous propagation code) and really odd things start to happen. choosing this order solves most practical problems, but there is nothing that makes this particular order actually mathematically sound. it's just Less Bad.

Varying had a similar problem, but because Varying has a singular propagation model and carries a singular value it is easy to simply eagerly vend each propagation wave, and when retreating up the call stack detect whether an older wave has been made redundant, and forget about doing the rest of it.

the data structures will have a far harder time accomplishing this. it's not so simple as "here in the call stack these things are now redundant or invalid, and there in the call stack we should send these out," we have to actually select intelligently and possibly even alter the indices to reflect other changes that have occurred.

it's a tricky problem.