SAXONICA |
saxon:function($arg1 as xs:string, $arg2 as xs:integer) ==> jt:net.sf.saxon.expr.UserFunctionCall
This function is available only in Saxon-SA
This function takes as its arguments the name and arity of a user-defined function (a function declared using
"declare function" in XQuery, or <xsl:function> in XSLT), and returns a value that represents the function and
can be used to invoke the function using
saxon:call. This allows higher-order
functions to be implemented in XSLT and XQuery, that is, functions that take other functions as arguments. An
example of such a higher-order function is
saxon:for-each-group, which
provides grouping capability in XQuery similar to that of the xsl:for-each-group
instruction in XSLT.
The arguments must be specified as literals (this function is always evaluated at compile time).
Here is an example, the textbook fold
function in XSLT:
<xsl:function name="f:fold">
<xsl:param name="sequence"/>
<xsl:param name="operation"/>
<xsl:param name="start-value"/>
<xsl:sequence select="if (empty($sequence))
then $start-value
else f:fold(remove($sequence, 1),
$operation,
saxon:call($operation,
$start-value,
$sequence[1])"/>
</xsl:function>
<xsl:function name="f:plus">
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:sequence select="$a + $b"/>
</xsl:function>
<xsl:function name="f:times">
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:sequence select="$a * $b"/>
</xsl:function>
<xsl:function name="f:sum">
<xsl:param name="sequence"/>
<xsl:sequence select="f:fold($sequence, saxon:function('f:plus', 2), 0)"/>
</xsl:function>
<xsl:function name="f:product">
<xsl:param name="sequence"/>
<xsl:sequence select="f:fold($sequence, saxon:function('f:times', 2), 0)"/>
</xsl:function>
Here is the same example in XQuery:
declare function f:fold (
$sequence as xs:double*, $operation, $start-value as xs:double) {
if (empty($sequence))
then $start-value
else f:fold(remove($sequence, 1),
$operation,
saxon:call($operation, $start-value, $sequence[1]))
};
declare function f:plus ($a as xs:double, $b as xs:double) {$a + $b};
declare function f:times ($a as xs:double, $b as xs:double) {$a * $b};
declare function f:sum ($sequence as xs:double*) as xs:double {
f:fold($sequence, saxon:function('f:plus', 2), 0)
};
declare function f:product ($sequence as xs:double*) as xs:double {
f:fold($sequence, saxon:function('f:times', 2), 1)
};
The result of f:sum(1 to 4)
is 10, while the result of f:product(1 to 4)
is 24.
Higher-order functions allow many generic functions such as fold
to
be written, and their availability in Saxon-SA turns XSLT and XQuery into fully-fledged
functional programming languages.
The type of the result of saxon:function is jt:net.sf.saxon.expr.UserFunctionCall
,
where the prefix jt
represents the URI http://net.sf.saxon/java-type
.