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

John,

 > 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".

That's right, I forgot about this one. And I think you make a good
case that my full-UI binding-evaluation interpretation in my previous
email is not what the spec authors intended to say.

But I think that the spec is unacceptably unclear on the notions of UI
bindings, dependencies in general, and UI dependencies in particular,
including their re-evaluation.

What we are doing in this thread is trying to figure out by reading
between the lines and reading across various sections what the authors
of the spec may well have meant, assuming they have not entirely lost
their common sense. It's more mind reading than spec reading!

This has been broken in the spec since 1.0, and 1.1 is already
slightly better, but still I think we need to fix this sooner rather
than later.

 > 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.

Thats sounds good to me.

 > 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.

I understand better now. I am still not sure that introducing implicit
instance data helps much. I can see how it would simplify certain
things a bit since currently we can only depend on instance data, and
have language that tackles changing and binding to that instance data.

But it would also be acceptable to generalize the dependency system to
introduce other "dependable" items accessible through XPath functions,
including repeat indexes, as first-class citizens, without resorting
to introducing implicit instance data.

In our XForms implementation, we have the concept of "dynamic state"
which represents the state of the XForms document which can change
over time. In our case this includes:

* Current instances
* Current values of repeat indexes
* Currently selected switch cases

If in the future XForms introduces a function called
selected-case(switchIndex). Like with index(), this function would
provide access to some data which is not held in an instance, yet this
data is part of the "dynamic state" of the document, can be set with
an action (xforms:toggle), and could potentially be used in binding
expressions.

There may be other cases, which may warrant a generalization of the
spec language used for specifying dependencies.

 > 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).

FWIW, in Orbeon Forms, we implement setting the index upon focus
change as the default action for DOMFocusIn on controls. So in our
case this focus change becomes automatically part of the deferred
update system.

This should be specified regardless of whether we support index() in
UI bindings or not.

 > 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.

Agreed.

This should be specified regardless of whether we support index() in
UI bindings or not.

 > 4) We get through all of that, and the situation is better, but the
 > dependency problem still exists.

 > 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 :-)

That's a tough one!

Regardless of whether we support index() in UI bindings or not, it
seems to be necessary to spec that during refresh, repeat indexes need
to be readjusted if out of bounds. This is (at least) a consequence of
accepting dynamic dependencies in UI bindings. Ajusting the indexes
upon xforms:insert or xforms:delete is simply not enough.

Then yes, if we support index() in UI bindings, then we need to
specify what happens to these dependencies while we are performing the
refresh.

 > 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.

My own conclusion is that this thread has been salutary so far. Just
above, we have identified the following to fix, whatever decision we
make on supporting index() in UI bindings:

* The whole question of UI bindings and dependencies needs to be
   clarified.

* setindex must be part of an action sequence upon focus change.

* setindex must be specified as a consequence of insert/delete.

* Repeat indexes must be ajudsted during refresh.

-Erik

-- 
Orbeon Forms - Web Forms for the Enterprise Done the Right Way
http://www.orbeon.com/

Received on Wednesday, 2 May 2007 07:23:52 UTC