# saxon:function()

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

This function is available only in Saxon-PE and Saxon-EE

From Saxon 9.2, provided XQuery 1.1 support is enabled and the query prolog specifies version "1.1", the syntax `my:function#3` can be used in place of the call `saxon:function('my:function', 3)`. The implementation (with either syntax) has also been extended so that it works with all functions, not only with user-written functions.

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 1.1 syntax):

                xquery version "1.1";
    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.

Next