<?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 2011-12-09T20:47:22.916Z--><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) ==> function()</b></p> <p><i>This function is available only in Saxon-PE and Saxon-EE. It is obsolescent, since the call <code>saxon:function("abc", 3)</code> can be replaced by the standard XPath 3.0 syntax <code>abc#3</code>.</i></p> <div class="boxed" style="border: solid thin; background-color: #B1CCC7; padding: 2px">From Saxon 9.2, provided XQuery 3.0 support is enabled and the query prolog specifies version "3.0", 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><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> </code> </pre> </div> <p>Here is the same example in XQuery (using XQuery 3.0 syntax):</p> <div class="codeblock" style="border: solid thin; background-color: #B1CCC7; padding: 2px"> <pre> <code>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) }; </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>