This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 26439 - [XSLT30] fn:fold-left in streamability rules can take type-determined usage into account (from note in test)
Summary: [XSLT30] fn:fold-left in streamability rules can take type-determined usage i...
Status: CLOSED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Last Call drafts
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-07-27 23:23 UTC by Abel Braaksma
Modified: 2014-09-05 11:55 UTC (History)
0 users

See Also:


Attachments

Description Abel Braaksma 2014-07-27 23:23:52 UTC
In test sf-fold-left-003 in test-set sf-fold-left (see top of this file: https://dvcs.w3.org/hg/xslt30-test/file/ed6d3af522b5/tests/strm/sf-fold-left/sf-fold-left-A.xsl) there's a comment with a "TODO", implying that TDU can be used with fold-left. I think this is correct. The full comment says it all:


> TODO: fold-left is defined in the current XSLT 3.0 draft to 
> have the operand usage N (Navigation) making it non-streamable. 
> This should be fixed; it should have type-determined usage 
> based on the type of the first argument of the function 
> provided in the third argument, if this is known. In the 
> meantime, we explicitly atomize the sequence to be processed
Comment 1 Abel Braaksma 2014-07-30 15:45:25 UTC
We considered this at F2F meeting in Hursley 30 July 2014 and concluded that the original bug description is a desirable change. Michael Kay has been given an action item to come up with a proposal.
Comment 2 Michael Kay 2014-08-01 11:14:16 UTC
Proposal:

fold-left() should use the GSR, with the operand usage of the first argument being the type-determined usage based on the type of the second argument of the supplied function.

Consider:

fold-left($seq, 0, declare function ($n as numeric, $m as numeric) as numeric {$n+$m})

where $seq is striding and consuming.

The TDU of $m is absorption, therefore the OU of $seq is absorption, therefore fold-left is grounded and consuming. 

How do we know it's grounded? Because both $zero and $fn are grounded...

We think there's potential for going beyond this e.g when using streamable stylesheet functions or known built-in functions but it gets tricky.

Still needs further work to flesh out the detail.
Comment 3 Michael Kay 2014-08-01 11:22:32 UTC
Note also that whatever we do for fold-left, we can probably also do the same or similar for filter and for-each, perhaps also for-each-pair.

For filter: it should behave like filter expressions if we know the supplied function is motionless (or has operand usage inspection). We can only know this for built-in functions (or inline functions if we choose to analyse them), for example it should be possible to make the following work:

filter(/*/x, function($n) {lang('en', $n)})

filter(/*/x, lang('en', ?))
Comment 4 Michael Kay 2014-08-21 17:14:35 UTC
Briefly discussed during today's telcon, though it is awaiting completion of an action to produce a proposal. The question was raised as to what kind of function items would be allowed in the third argument. Only allowing built-in functions would be rather restrictive. Allowing functions that atomize their arguments should be OK (but perhaps we already allow that?). To be at all useful, we need to allow user-defined functions (e.g. inline functions) and it's not clear how we can constrain them suitably.
Comment 5 Michael Kay 2014-09-04 21:18:58 UTC
The WG accepted the proposal in

https://lists.w3.org/Archives/Member/w3c-xsl-wg/2014Sep/0002.html

(member-only)
Comment 6 Michael Kay 2014-09-05 11:43:00 UTC
For fn:filter, the rules don't quite work in the same way. By analogy with filter expressions, filter($seq, $f) has the posture and sweep of $f provided that a call on $f is motionless. We can be sure that a dynamic call on $f is motionless only if:

(a) $seq is grounded, or

(b) $f is a known built-in function such as fn:nilled#1 where the argument has inspection usage, or 

(c) $f is an inline function whose body we are prepared to analyse.

But (b) covers so few useful cases that it really isn't worth bothering, especially as these cases can always be expressed by a simple filter expression: emp[nilled()]; and (c) is going into new territory that is best left untouched for now.

Given that case (a) is already handled, I'm going to make no change for fn:filter.
Comment 7 Michael Kay 2014-09-05 11:55:59 UTC
The agreed changes have been applied, affecting fn:fold-left, fn:for-each, and fn:for-each-pair.