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 29712 - [xslt3.0] Why are streamable stylesheet functions required to be consuming?
Summary: [xslt3.0] Why are streamable stylesheet functions required to be consuming?
Status: CLOSED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Candidate Recommendation
Hardware: PC All
: 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: 2016-06-29 09:27 UTC by Michael Kay
Modified: 2016-10-06 18:42 UTC (History)
1 user (show)

See Also:


Attachments

Description Michael Kay 2016-06-29 09:27:32 UTC
For streamability categories absorbing, shallow-descent, and deep-descent, we require the function body to be consuming. Is there any reason why we don't also allow it to be motionless?

This restriction requires the user to have a very good understanding of the circumstances under which expressions are consuming vs motionless. For example:

<xsl:function streamability="absorbing">
  <xsl:param name="n" as="node()"/>
  <xsl:sequence select="exists($n/@*) or exists($n/*)"/>
</xsl:function>

is allowed, but

<xsl:function streamability="absorbing">
  <xsl:param name="n" as="node()"/>
  <xsl:sequence select="exists($n/@*) or has-children($n)"/>
</xsl:function>

is not, because has-children() is motionless.

I can't think of any other cases where we allow an expression to be consuming and don't also allow it to be motionless.
Comment 1 Michael Kay 2016-06-29 09:30:56 UTC
And if the argument is that it's easy enough to change the value of the streamability attribute to "inspection" in such cases, that's not true if you are overriding an absorbing function - the overriding function has to have the same streamability category.
Comment 2 Michael Kay 2016-06-30 21:10:25 UTC
Note, markup in the spec suggests that this was a conscious decision, made somewhere in the course of the extensive debate on bug #27571.
Comment 3 Michael Kay 2016-07-01 08:24:58 UTC
Another observation: perhaps the concern is about how the implementation copes with the situation where the function doesn't consume the input. But it has to deal with that situation anyway. For example the function body might be

if (current-date() < xs:date('2000-01-01') 
then sum($input/@value)
else 0

which has consuming sweep (the wider of the sweeps of the two conditional branches), but doesn't actually consume anything.
Comment 4 Abel Braaksma 2016-07-02 08:08:53 UTC
ACTION 2016-06-30-003: ABr to review bug 29712 in detail and determine whether changing the rule would lead to inconsistencies or implementation issues.

I've been over previous mail and earlier bugs. I could recollect that we removed the ability for variants of resulting posture (a filter must be striding, grounded is not allowed). I can't recollect we did the same consciously for the sweep of the body of the function.

I see no problem in allowing this and agree to Mike's assessments in the previous comments.

A processor could, if they want, raise a warning, telling users they should use there resources more carefully and choose inspect instead of absorb.

This does raise a related question though: why don't we make our lives a bit simpler w.r.t. the rules. Some rules in this section would, for instance, be a bit easier if we force users to use a type signature of U{N} for the return types of filter, shallow-descent and deep-descent (the rules already require the function body to return nodes).


(In reply to Michael Kay from comment #3)
> if (current-date() < xs:date('2000-01-01') 
> then sum($input/@value)
> else 0
> 
> which has consuming sweep (the wider of the sweeps of the two conditional
> branches), but doesn't actually consume anything.
The wider of the sweeps here is dependent on the type of the parameter (does it accept more-than-one?), which can then be either consuming or motionless.
Comment 5 Michael Kay 2016-07-10 17:25:18 UTC
It's not strictly true that the rules for filter, shallow-descent, and deep-descent require the function to return nodes; they require its posture to be striding or crawling, but an expression such as

(child::x, 23)

is striding even though its result includes non-nodes. So I'm inclined not to add a rule requiring the type signature of these functions to declare a return type of U{N}.

Apart from this, the WG approved the change to allow the function body to be motionless, and I have applied that part of the change.
Comment 6 Abel Braaksma 2016-07-21 14:08:51 UTC
> (child::x, 23)
Isn't that also U{N}? 

But I agree, the change wouldn't fix anything. The rationale was it would make parts of the rules more readable. But we already use "type adjusted posture and sweep" in some of the rules, which comes down to the same (if the result type is xs:string, the posture will be grounded, even on an expression like x/y/z).
Comment 7 Michael Kay 2016-07-21 16:50:00 UTC
The WG accepted the proposal to allow the function body to be consuming, but did not accept the suggestion in comment #4 to place a restriction on the function type signature.