Component binding in inline functions

I've been struggling today with a problem involving component bindings in inline functions. It may be that the spec has the answer, but it certainly doesn't leap out of the page.

I've written a test case override-v-013 to illustrate:

Package A has

<xsl:use-package name="B">
    <xsl:override>
      <xsl:variable name="var" as="xs:integer" select="4"/>
    </xsl:override>
  </xsl:use-package>
  
  <xsl:template name="xsl:initial-template">
    <out>{f:f()()}</out>
  </xsl:template>

Package B has

<xsl:variable name="var" as="xs:integer" select="3" visibility="public"/>
  
  <xsl:function name="f:f" visibility="public">
    <xsl:sequence select="function() { $var }"/>
  </xsl:function>

and the question is, does this output "3" or "4" (and if so why: no prizes for getting the right answer for the wrong reason....)

In English: package A calls a function in package B, which returns an inline function which in return has a reference to a global variable, and the global variable is overridden in A.

The inline function isn't itself a "component". I think that what happens here is as follows:

(a) There are two components named f:f, an explicit one in B and an implicit one in B.

(b) Depending which version of f:f you call, you get a different (inline) function returned.

(c) The binding of the variable reference $var is determined by which version of f:f you call.

(d) The implication of this is that the global variable $var effectively becomes part of the closure of the returned inline function, just as a reference to a local variable would be.

(e) Since we've called the version of f:f in B, the closure of the returned function item contains a reference to the version of $var with value 4, and the result of the transformation is therefore 4.

Anyone disagree?

Note that the XPath spec of inline functions talks only of "nonlocal variable bindings", by which it means variables that are in scope within the inline function body, but not declared within it. It doesn't distinguish external local variables from external global variables. In my implementation, I have always treated the two cases differently, because I've assumed that global variables can only have one value. But it seems I'm going to have to change this.

Michael Kay
Saxonica 

Received on Tuesday, 5 July 2016 17:40:48 UTC