# xsl:function

The `xsl:function` 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.

Example:

    <xsl:function name="my:factorial">
    <xsl:param name="number" as="xs:integer"/>
    <xsl:sequence as="xs:integer"
                select="if ($number=0) then 1 else $number * my:factorial($number-1)"/>

In limited circumstances, stylesheet functions (`xsl:function`) now optimise tail-recursion. The circumstances are that the `select` expression of the `xsl:result` instruction must contain a call on the same function as the `then` or `else` 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):

    <xsl:function name="x:factorial">
        <xsl:param name="acc" as="xs:integer?"/>
        <xsl:param name="n" as="xs:integer"/>
        <xsl:sequence as="xs:integer"
             select="if ($n = 1)
                     then $acc
                     else x:factorial($acc*$n, $n - 1)" />
    </xsl:function>

The call `x:factorial(1, 5)` returns 120.

Saxon defines an extra attribute on `xsl:function`: `saxon:memo-function="yes"` 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 saxon:memo-function.

Expand | Next