What is the call-site of errors in sequences?

I am revisiting certain aspects of our type system, esp. w.r.t. lazy evaluation and I was wondering about the following:

 

<xsl:variable name="errors" select="1,2,error(xs:QName('err:test3')),4,error(xs:QName('err:test5'))" />

<xsl:try>

   <xsl:for-each select="$errors">

      <xsl:try>

         <xsl:sequence select="." />

         <xsl:catch>

            <xsl:sequence select=" 'lazy-throw' " />

         </xsl:catch>

      </xsl:try>

   </xsl:for-each>

   <xsl:catch>

      <xsl:sequence select="'eager-throw'" />

   </xsl:catch>

</xsl:try>

 

The question is: does the for-each do the evaluation here and should it throw when it encounters the third element, or does the xsl:sequence do the evaluation, and it will throw twice, leading to output (1,2,'lazy-throw',4,'lazy-throw'), or is this implementation defined?

 

I think the latter: implementation-defined/dependent, since the order of execution is undefined and we may say argue that the items in the sequence only get evaluated once inside the body of the for-each. Of course, an implementation may choose to do so earlier on and raise the error *outside* the try/catch, leading to a single output (because of rollback) of 'eager-throw'.

 

And if this isn't in a final state (i.e., if the code segment is itself wrapped inside a variable), it may never show 'lazy-throw', or 'eager-throw', depending on how that variable is used later on.

 

On the flip side, I don't think there is an implementation-independent way of getting only the non-error items in the sequence, as on each access, even on declaration of the variable, eager evaluation *may* already throw, leading to the whole code segment to blow up.

 

Cheers,

Abel

Received on Thursday, 22 September 2016 12:29:11 UTC