data binding setters / why no infinite recursion?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

data binding setters / why no infinite recursion?

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
[hidden email]
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel
Reply | Threaded
Open this post in threaded view
|

Re: data binding setters / why no infinite recursion?

Robert Krahn-4
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


On Mon, Sep 15, 2014 at 4:10 PM, Davide Della Casa <[hidden email]> wrote:
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
[hidden email]
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel



_______________________________________________
lively-kernel mailing list
[hidden email]
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel
Reply | Threaded
Open this post in threaded view
|

Re: data binding setters / why no infinite recursion?

Davide Della Casa
In reply to this 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)



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

On 16 Sep 2014, at 00:39, Lars <[hidden email]> wrote:

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

On 15 September 2014 16:10, Davide Della Casa <[hidden email]> wrote:
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
[hidden email]
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel




_______________________________________________
lively-kernel mailing list
[hidden email]
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel
Reply | Threaded
Open this post in threaded view
|

Re: data binding setters / why no infinite recursion?

Robert Krahn-4
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!

On Mon, Sep 15, 2014 at 5:02 PM, Davide Della Casa <[hidden email]> wrote:
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

On 16 Sep 2014, at 00:39, Lars <[hidden email]> wrote:

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

On 15 September 2014 16:10, Davide Della Casa <[hidden email]> wrote:
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
[hidden email]
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel




_______________________________________________
lively-kernel mailing list
[hidden email]
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel



_______________________________________________
lively-kernel mailing list
[hidden email]
http://lists.hpi.uni-potsdam.de/listinfo/lively-kernel