saxon:function()

saxon:function($arg1 as xs:string, $arg2 as xs:integer) ==> function()

This function is available only in Saxon-PE and Saxon-EE. It is obsolescent, since the call saxon:function("abc", 3) can be replaced by the standard XPath 3.0 syntax abc#3.

This function takes as its arguments the name and arity of a function, 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). The first argument gives the name of the function as a lexical QName (using the default function namespace if unprefixed), the second gives the function arity (number of arguments).

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 (using XQuery 3.0 syntax):

xquery version "3.0"; 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, f:plus#2, 0) }; declare function f:product ($sequence as xs:double*) as xs:double { f:fold($sequence, 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-EE turns XSLT and XQuery into fully-fledged functional programming languages.

The type of the result of saxon:function is function(), a new type introduced in XQuery 1.1 - it is a third subtype of item() alongside nodes and atomic values.