<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet href="../make-menu.xsl" type="text/xsl"?><html>
   <head>
      <this-is section="xsl-elements" page="function" subpage=""/>
      <!--
           Generated at 2010-10-29T18:20:48.427+01:00--><title>Saxonica: XSLT and XQuery Processing: xsl:function</title>
      <meta name="coverage" content="Worldwide"/>
      <meta name="copyright" content="Copyright Saxonica Ltd"/>
      <meta name="title" content="Saxonica: XSLT and XQuery Processing: xsl:function"/>
      <meta name="robots" content="noindex,nofollow"/>
      <link rel="stylesheet" href="../saxondocs.css" type="text/css"/>
   </head>
   <body class="main">
      <h1>xsl:function</h1>
      <p>The <code>xsl:function</code> element defines a function within a stylesheet. The function is written
in XSLT but it may be called from any XPath expression in the stylesheet. It must have a non-default
namespace prefix.</p>
      <p>Example:</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>&lt;xsl:function name="my:factorial" as="xs:integer"&gt;
&lt;xsl:param name="number" as="xs:integer"/&gt; 
&lt;xsl:sequence 
            select="if ($number=0) then 1 else $number * my:factorial($number-1)"/&gt;</code>
         </pre>
      </div>
      <p>In limited circumstances, stylesheet functions (<code>xsl:function</code>) now optimise tail-recursion.
The circumstances are that the <code>select</code> expression of the <code>xsl:result</code> instruction
must contain a call on the same function as the <code>then</code> or <code>else</code> part of a
conditional expression (which may be nested in further conditional expressions). It may require a little
care to write functions to exploit this. The example above is not tail-recursive, because
the recursive call is within an arithmetic expression: the multiplication takes place on return
from the recursive call. It can be recast in tail-recursive form by adding an extra parameter (which should
be set to 1 on the initial call):</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>&lt;xsl:function name="x:factorial"&gt;
    &lt;xsl:param name="acc" as="xs:integer?"/&gt;
    &lt;xsl:param name="n" as="xs:integer"/&gt;
    &lt;xsl:sequence as="xs:integer" 
         select="if ($n = 1) 
                 then $acc
                 else x:factorial($acc*$n, $n - 1)" /&gt;
&lt;/xsl:function&gt;</code>
         </pre>
      </div>
      <p>The call <code>x:factorial(1, 5)</code> returns 120.</p>
      <p>Saxon defines an extra attribute on <code>xsl:function</code>: <code>saxon:memo-function="yes"</code>
indicates that Saxon should remember the
results of calling the function in a cache, and if the function is called again
with the same arguments, the result is retrieved from the cache rather than being
recalculated. Further details: see 
<a class="bodylink" href="../extensions/attributes/memo-function.xml">saxon:memo-function</a>.</p>
      <table width="100%">
         <tr>
            <td>
               <p align="right"><a class="nav" href="if.xml">Next</a></p>
            </td>
         </tr>
      </table>
   </body>
</html>