Is there an overview of how Visage implements reactivity? I
understand the semantics for the user; I'm just curious how it
compiles (since there are many possibilities).
I've been poking around with decompiling visagec-produced class files,
and noticed a few basic things:
- the compiler statically determines the dependency graph (not
surprising, but interesting since it's different from / harder than
the dynamic approach some other systems take, e.g. knockout, angular,
meteor, ...)
- it maintains for each variable some metadata flags (VFLG) that
indicate among other things freshness/dirtiness
- reading a variable `x` is always done via a get$x() call that checks
these flags and updates $x if necessary (if dirty) by re-evaluating
the entire original bind expression (making other get$y() call on the
dependencies)
- writing a variable `x` is always done via a set$y() call that
updates the flags and invalidates dependents with invalidate$y
- this metadata and getter/setter pair are generated only as
necessary, requiring whole-program analysis / preventing binding from
working across dynamically loaded Visage code
- the above only describes simple static/global bindings; things get
more complicated when binding fields across object instances, which
seems to result in a dependency graph being established dynamically
rather than being hard-coded
These are my notes so far. I'd love to learn more, if anyone has
pointers to good high-level resources. The only other "archaeological
study" I could find on this is (which seems to be based on older
versions):
http://blog.cedarsoft.com/2010/05/analyzing-javafx/
I also had a specific question. I thought lazy evaluation was only
done by `bind lazy`, but it appears that the laziness is there even
with normal `bind`, as opposed to eager updates (recomputing x only
happens in get$x(), and not in set$y(), where x depends on y). I
actually didn't notice any difference between the generated code for
`bind` and `bind lazy`. If laziness is indeed how normal `bind`s work
too, then when do the updates get propagated in a GUI/event-loop app?
(On user event / periodic polling?)
Thanks!
--
Yang Zhang
http://yz.mit.edu/