<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet href="../../make-menu.xsl" type="text/xsl"?><html>
   <head>
      <this-is section="extensions" page="functions" subpage="function"/>
      <!--
           Generated at 2010-10-29T18:20:48.427+01:00--><title>Saxonica: XSLT and XQuery Processing: saxon:function()</title>
      <meta name="coverage" content="Worldwide"/>
      <meta name="copyright" content="Copyright Saxonica Ltd"/>
      <meta name="title" content="Saxonica: XSLT and XQuery Processing: saxon:function()"/>
      <meta name="robots" content="noindex,nofollow"/>
      <link rel="stylesheet" href="../../saxondocs.css" type="text/css"/>
   </head>
   <body class="main">
      <h1>saxon:function()</h1>
      <p><b>saxon:function($arg1 as xs:string, $arg2 as xs:integer) ==&gt; function()</b></p>
      <p><i>This function is available only in Saxon-PE and Saxon-EE</i></p>
      <div class="boxed"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">From Saxon 9.2, provided XQuery 1.1 support is enabled and the query prolog specifies version "1.1",
the syntax <code>my:function#3</code> can be used in place of the call <code>saxon:function('my:function', 3)</code>.
The implementation (with either syntax) has also been extended so that it works with all functions, not only
with user-written functions.</div>
      <p>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 
<a class="bodylink" href="../../extensions/functions/call.xml">saxon:call</a>. 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 
<a class="bodylink" href="../../extensions/functions/for-each-group.xml">saxon:for-each-group</a>, which
provides grouping capability in XQuery similar to that of the <code>xsl:for-each-group</code> instruction in XSLT.</p>
      <p>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).</p>
      <p>Here is an example, the textbook <code>fold</code> function in XSLT:</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>&lt;xsl:function name="f:fold"&gt;
  &lt;xsl:param name="sequence"/&gt;
  &lt;xsl:param name="operation"/&gt;
  &lt;xsl:param name="start-value"/&gt;
  &lt;xsl:sequence select="if (empty($sequence))
                        then $start-value
                        else f:fold(remove($sequence, 1), 
                                    $operation,
                                    saxon:call($operation, 
                                               $start-value, 
                                               $sequence[1])"/&gt;
&lt;/xsl:function&gt;

&lt;xsl:function name="f:plus"&gt;
  &lt;xsl:param name="a"/&gt;
  &lt;xsl:param name="b"/&gt;
  &lt;xsl:sequence select="$a + $b"/&gt;
&lt;/xsl:function&gt;

&lt;xsl:function name="f:times"&gt;
  &lt;xsl:param name="a"/&gt;
  &lt;xsl:param name="b"/&gt;
  &lt;xsl:sequence select="$a * $b"/&gt;
&lt;/xsl:function&gt;

&lt;xsl:function name="f:sum"&gt;
  &lt;xsl:param name="sequence"/&gt;
  &lt;xsl:sequence select="f:fold($sequence, saxon:function('f:plus', 2), 0)"/&gt;
&lt;/xsl:function&gt;

&lt;xsl:function name="f:product"&gt;
  &lt;xsl:param name="sequence"/&gt;
  &lt;xsl:sequence select="f:fold($sequence, saxon:function('f:times', 2), 0)"/&gt;
&lt;/xsl:function&gt;                                    

</code>
         </pre>
      </div>
      <p>Here is the same example in XQuery (using XQuery 1.1 syntax):</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>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)
};

</code>
         </pre>
      </div>
      <p>The result of <code>f:sum(1 to 4)</code> is 10, while the result of <code>f:product(1 to 4)</code>
is 24.</p>
      <p>Higher-order functions allow many generic functions such as <code>fold</code> to 
be written, and their availability in Saxon-EE turns XSLT and XQuery into fully-fledged
functional programming languages.</p>
      <p>The type of the result of saxon:function is <code>function()</code>, a new type introduced in
  XQuery 1.1 - it is a third subtype of <code>item()</code> alongside nodes and atomic values.</p>
      <table width="100%">
         <tr>
            <td>
               <p align="right"><a class="nav" href="generateid.xml">Next</a></p>
            </td>
         </tr>
      </table>
   </body>
</html>