Re: [Fwd: LC: Issue with repeat index and rebuild]

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