Discussion:
[lively-kernel] data binding setters / why no infinite recursion?
Davide Della Casa
2014-09-15 23:10:41 UTC
Permalink
In the Celsius - Fahrenheit example, each text box is connected to the other one.

So changing the Celsius calculates the Fahrenheit and vice-versa.

Question is: why does it not go in infinite updates between the two text boxes?

I’m going through the code and “How connect works” and can’t figure out what’s preventing the infinite updates. The original Ingalls 1988 Fabrik paper mentions that this loop can/should/is avoided but it doesn’t give specifics (“with some care” and “bidirectionality…shorthand for multiple paths” page 5). There doesn’t seem to be a check in “connect” or “update” or the setter. The setter seems to do an update, so why doesn’t changing the C box cause the setter of F to invoke updates on C again?

Also tried to look for “loop” in source code https://github.com/LivelyKernel/LivelyKernel/search?utf8=%E2%9C%93&q=loop&type=Code but nothing jumps to the eye.

What’s the trick I’m missing?

(BTW the edit/select/move-cursor behaviour in the text boxes when they are connected is glitchy)

Cheers,
Davide Della Casa
Robert Krahn
2014-09-15 23:30:50 UTC
Permalink
Hi, Davide --

Dan's original Fabrik does a topological sort before evaluating connections
when I'm not mistaken.

Lively's approach is much simpler: If a connection is active it is marked
as such (as kind of a dynamic variable) and subsequent activations won't
trigger dependencies.

When you look at AttributeConnection>>update (eval
$world.browseCode("lively.bindings.Core", "AttributeConnection",
"lively.bindings.Core");
in Lively) then the first line does the activation check.

Best,
Robert
Post by Davide Della Casa
In the Celsius - Fahrenheit example, each text box is connected to the other one.
So changing the Celsius calculates the Fahrenheit and vice-versa.
Question is: why does it not go in infinite updates between the two text boxes?
I’m going through the code and “How connect works” and can’t figure out
what’s preventing the infinite updates. The original Ingalls 1988 Fabrik
paper mentions that this loop can/should/is avoided but it doesn’t give
specifics (“with some care” and “bidirectionality
shorthand for multiple
paths” page 5). There doesn’t seem to be a check in “connect” or “update”
or the setter. The setter seems to do an update, so why doesn’t changing
the C box cause the setter of F to invoke updates on C again?
Also tried to look for “loop” in source code
https://github.com/LivelyKernel/LivelyKernel/search?utf8=%E2%9C%93&q=loop&type=Code
<https://github.com/LivelyKernel/LivelyKernel/search?utf8=✓&q=loop&type=Code> but
nothing jumps to the eye.
What’s the trick I’m missing?
(BTW the edit/select/move-cursor behaviour in the text boxes when they are
connected is glitchy)
Cheers,
Davide Della Casa
_______________________________________________
lively-kernel mailing list
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel
Davide Della Casa
2014-09-16 00:02:11 UTC
Permalink
indeed had just traced through it.

For future Google searchers: it’s the “isActive” flag of the AttributeConnection.

It’s set at “this.isActive = true;” in the update method.

Update causes the setter in F to go to work. the setter in F calls the updater of C, but here we stop because we check the flag we set before.

(I’m short on time now, if I had the time I’d mark that flag to be explained in the code)



On separate note, targetProp/targetMethod turn loosely into each other:

initialize: function(source, sourceProp, target, targetProp, spec)

should probably be something like

initialize: function(source, sourceProp, target, targetPropOrMethod, spec)

and the ambivalence of that value “targetPropOrMethod “ should be probably propagated through, it seems that the naming “picks” one or the other value a little randomly along the code, e.g. in init function:

this.targetMethodName = targetProp;

which seems strange, at least to me.

Cheers,
Davide Della Casa
Hi Davide,
The trick is somewhere in the binding activation. The implementation prevents the same connection to be triggered twice in the same scope. So changing C updates F updates C, but then the recursion stops. You can still run into infinite loops if you use asynchronous updater, afaik. But most of the base cases should be covered by that simple change of semantics.
Best,
Lars
In the Celsius - Fahrenheit example, each text box is connected to the other one.
So changing the Celsius calculates the Fahrenheit and vice-versa.
Question is: why does it not go in infinite updates between the two text boxes?
I’m going through the code and “How connect works” and can’t figure out what’s preventing the infinite updates. The original Ingalls 1988 Fabrik paper mentions that this loop can/should/is avoided but it doesn’t give specifics (“with some care” and “bidirectionality…shorthand for multiple paths” page 5). There doesn’t seem to be a check in “connect” or “update” or the setter. The setter seems to do an update, so why doesn’t changing the C box cause the setter of F to invoke updates on C again?
Also tried to look for “loop” in source code https://github.com/LivelyKernel/LivelyKernel/search?utf8=%E2%9C%93&q=loop&type=Code but nothing jumps to the eye.
What’s the trick I’m missing?
(BTW the edit/select/move-cursor behaviour in the text boxes when they are connected is glitchy)
Cheers,
Davide Della Casa
_______________________________________________
lively-kernel mailing list
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel
Robert Krahn
2014-09-16 18:13:15 UTC
Permalink
The criticism is justified, the naming is confusing. While implementing we
found out that the mechanism is more general than we first thought but
never changed the names. The next time we swipe over it we'll improve it :)
Thanks for the feedback!
Post by Davide Della Casa
indeed had just traced through it.
For future Google searchers: it’s the “isActive” flag of the
AttributeConnection.
It’s set at “this.isActive = true;” in the update method.
Update causes the setter in F to go to work. the setter in F calls the
updater of C, but here we stop because we check the flag we set before.
(I’m short on time now, if I had the time I’d mark that flag to be
explained in the code)
* initialize: function(source, sourceProp, target, targetProp, spec)*
should probably be something like
* initialize: function(source, sourceProp, target, targetPropOrMethod,
spec)*
and the ambivalence of that value “*targetPropOrMethod* “ should be
probably propagated through, it seems that the naming “picks” one or the
* this.targetMethodName = targetProp;*
which seems strange, at least to me.
Cheers,
Davide Della Casa
Hi Davide,
The trick is somewhere in the binding activation. The implementation
prevents the same connection to be triggered twice in the same scope. So
changing C updates F updates C, but then the recursion stops. You can still
run into infinite loops if you use asynchronous updater, afaik. But most of
the base cases should be covered by that simple change of semantics.
Best,
Lars
Post by Davide Della Casa
In the Celsius - Fahrenheit example, each text box is connected to the other one.
So changing the Celsius calculates the Fahrenheit and vice-versa.
Question is: why does it not go in infinite updates between the two text boxes?
I’m going through the code and “How connect works” and can’t figure out
what’s preventing the infinite updates. The original Ingalls 1988 Fabrik
paper mentions that this loop can/should/is avoided but it doesn’t give
specifics (“with some care” and “bidirectionality
shorthand for multiple
paths” page 5). There doesn’t seem to be a check in “connect” or “update”
or the setter. The setter seems to do an update, so why doesn’t changing
the C box cause the setter of F to invoke updates on C again?
Also tried to look for “loop” in source code
https://github.com/LivelyKernel/LivelyKernel/search?utf8=%E2%9C%93&q=loop&type=Code but
nothing jumps to the eye.
What’s the trick I’m missing?
(BTW the edit/select/move-cursor behaviour in the text boxes when they
are connected is glitchy)
Cheers,
Davide Della Casa
_______________________________________________
lively-kernel mailing list
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel
_______________________________________________
lively-kernel mailing list
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel
Loading...