- From: John Boyer <boyerj@ca.ibm.com>
- Date: Tue, 1 May 2007 20:16:27 -0700
- To: ebruchez@orbeon.com
- Cc: public-forms@w3.org, www-forms-editor@w3.org, www-forms-editor-request@w3.org
- Message-ID: <OF9466A65E.BCF8EA46-ON882572CF.0007FF6F-882572CF.0011FC2A@ca.ibm.com>
Hi Erik, Yikes, requiring a refresh on any focus change would be disastrously inefficient if it were required to examine all UI bindings as your email below suggests. The language on refresh supports reevaluation "as necessary". The meaning of "as necessary" is a little clearer in Section 7.5, which discusses the details of bindings, including UI bindings. The language there is steeped in the notion of "dependencies", and in turn dependencies are established based on references to nodes of instance data (in 4.3.6). The issue I'm raising is four-fold. 1) The current definitions don't support the idea that a UI binding should be re-evaluated on refresh the UI binding references a repeat index that changes. Perhaps the easiest way to fix this would be to add index() to the list of functions that create "dynamic dependencies" in 7.5.1. I think the end of your email below suggests doing this. By classifying the invocation of index() as a dynamic reference, it means you could safely use them in both actions and UI bindings, but that their use in a model binding expression would be limited to situations where a rebuild could be forced by the author. This was the main part of my original concern; I had previously heard suggestions that the use of index() in a model binding expression would force a rebuild if the repeat index changed. Making index() be a dynamic dependency works for me because it doesn't cause rebuild to happen. However, the reason index() was not included in dynamic dependencies is the same reason that now() isn't really mentioned. It isn't dependent on any data, so how can it be a dynamic dependency? The notion of dynamic dependency was created to express the idea that an XPath expression could depend on instance nodes other than the ones currently referenced by the expression. For example, something non-trivial in an XPath predicate is a dynamic dependency because when you change the nodes in the predicate, it filters the nodes before the predicate in a different way, leading to "dynamic" dependencies. This is how I got to the idea of regarding repeat indexes as implicit instance data. 2) Assuming we did make index() into a dynamic dependency, we still have the larger problem that most repeat index changes are not performed by a proper action sequence. I think the easiest fix here would be to say that the change of focus that also causes a change of index does so by invocation of the setindex action followed by 'deferred update'. This has to happen in the last paragraph of 9.3.8. The setindex action needs to set the refresh flag. (9.3.7 and the beginning of Section 10). 3) Actions like insert and delete, which are currently specified as also affecting repeat indexes, would ideally quit doing that in favor of having the repeats themselves respond by changing their own indices in response to inserted/deleted data. Yet this still leaves repeat index changes as side effects of insertion/deletion, so those index changes should be done by proper setindex so that the refresh is deferred. 4) We get through all of that, and the situation is better, but the dependency problem still exists. However, by settling on index() as a dynamic dependency, we focus on UI bindings, and I can now only reproduce the dependency problem by relying on part of the spec that seems to be missing :-( You now how when a delete happens, if the resulting nodeset is smaller, so there is a chance tha the index has to be adjusted downward. Well, I had rather assumed the same thing would happen to a repeat whose nodeset changed via dynamic dependency rewiring. Unfortunately, I haven't run across the supporting text, so by all means feel free to disagree here! But supposing the index does get updated when the new nodeset for the repeat is computed. Then we have a case where, during the re-evaluation of stale nodesets, more nodesets become stale. There are lots of ways one can keep track of stale UI bindings. Because there's nothing in the spec right now that jumps out at the implementer and says that the number of stale UI bindings can increase while re-evaluating the stale UI bindings, I'd bet most implementers would just pick up the list, iterate it, and move on with the refresh. Clearly, more would be needed. The problem is how much more. Suppose a stale nodeset A begets a stale nodeset B which begets a stale nodesets C. So, you'd think you have to keep looking for more stale nodes every time you finish processing the stale nodes you know about. But what if you have a circular dependency of repeat index references? Maybe, you think, you should set up a rule saying that rewiring can only re-evaluate a nodeset one time across all iterations. Nice, gets you out of the endless loop, but what if the B was also dependent on C? You still end up with an incorrect algorithm. But at least it doesn't take forever to get the wrong answer :-) ========================= In conclusion, my original post was getting at the fact that we either need to restrict index() to use in the XPaths of actions only, or we have to fix it so that it works in either UI bindings (something like the above), or in UI bindings and model binding expressions (something more complex than the above, perhaps based on implicit instance data). So long as it's clear that the current spec is insufficient to imply that index() works properly in UI bindings and esp. in model binding expressions, then which way the fix goes is less of an issue for me. The main concern is that we don't end up with an implicit *rebuild* every time a repeat index changes, which was suggested in the past. Cheers, John M. Boyer, Ph.D. STSM: Lotus Forms Architect and Researcher Chair, W3C Forms Working Group Workplace, Portal and Collaboration Software IBM Victoria Software Lab E-Mail: boyerj@ca.ibm.com Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer Erik Bruchez <ebruchez@orbeon.com> Sent by: www-forms-editor-request@w3.org 05/01/2007 04:48 AM Please respond to ebruchez@orbeon.com To public-forms@w3.org cc www-forms-editor@w3.org Subject Re: [Fwd: LC: Issue with repeat index and rebuild] John, > By refresh on focus change, I did assume you mean refresh on repeat > index change. No, I really meant refresh on focus change ;-) We were talking about the user-triggered focus change causing an index change. But I think we understand each other. > This was because it already seemed clear from the three repeat > example that a system of dependencies would be needed to work out > refresh order. A corollary to that is that a dependency system > would have to be worked out even for the simpler case you presented. I started writing "I agree", then figured that I was not sure I grasped the necessity of the dependency mechanism. Currently, XForms does not specify a dependency mechanism for UI controls. This why the spec for "refresh" is the way it is. It specifies in section "4.6.7 Sequence: Value Change": "3. xforms-refresh performs reevaluation of UI binding expressions [...]" This means all UI bindings. A well-functioning dependency mechanism would allow getting rid of this point, because only the UI bindings that need updating would be updated. (Possibly in that case xforms:rebuild would force all bindings to be recomputed.) But this dependency mechanism would be mainly a performance optimization. So to get back to my example: the form user indirectly causes an index to change. When that happens, the "flag" for refresh is set. Upon the next refresh, the UI correctly reflects the data, including all current values of the indexes. So there is no problem, right? > The problem with saying that a refresh will occur if a repeat index > changes is that the refresh has no way of knowing that a particular > repeat's nodeset is stale if the only different thing is the result > that index() would return if it were invoked again. In other words, > we would have to say that every repeat index creates some *implicit* > instance data, and that the invocation of index('X') creates a > dependency between the invoking XPath expression and the implicit > instance data representing the index of repeat X. I don't think the above is correct, because: 1. There is currently no dependency mechanism for UI controls. 2. All UI bindings are re-evaluated upon refresh anyway. So you don't need to know which binding changed, the UI behaves as if all of them did. Even so, referring to "implicit instance data" would be an implementation detail. Currently, XForms does not specify a dependency system between controls and instance data. So I think that if we defined a dependency mechanism, we wouldn't necessarily need to introduce "implicit instance data". This would be a way of looking at it, but you could as well consider repeat indexes as first-class objects in the dependency system. > Finally, I noticed you questioned why index() could not be invoked > from a UI binding if the spec didn't support refreshment of the > containing XPath expression when the referenced index changes. I > believe the answer is simply because the function invocation in a UI > binding does not do what the form author expects. When you first > proposed your two repeat example, I believe you gave it as something > that *should* work, and the problem is that it doesn't.. So, unless > the problem is fixed, we should at least create a binding or compute > exception when index() is misused (depending where it appears) so > that a form author can at least find out that he or she is doing > something unsupported. Basically, we want to reduce the number of > places where a form author sits for hours trying to figure out what > they must have done wrong to cause the form not to update properly. > This is done by either patching or repairing the hole in the spec. I understand the rationale in theory, but I don't think you are right saying that it doesn't do what the author wants as I show above. If we don't allow index() in the bindings, then we force form authors who want to have a binding depending on index() to use @calculate or xforms:setvalue to store the value of the index in instance data, and then to bind their controls using an XPath expression referring to that instance data. This introduce a dynamic dependency which is in fact no different from directly using index(), except that it causes way more work for the form author. -Erik -- Orbeon Forms - Web Forms for the Enterprise Done the Right Way http://www.orbeon.com/
Received on Wednesday, 2 May 2007 03:16:49 UTC