Re: Recursion in XPath 3.1 inline function definition

This issue is well known in XPath 3.

There is a way to use recursion with anonymous (inline) functions in pure
XPath 3, and I reported it in my blog and at the Balisage 2013 conference.
Since then, I have built my own, pure XPath 3.1 function libraries using
this technique.

Here is a simple example:

let $fact-base := function($n as xs:integer,
                   $f1 as function(xs:integer,
                   function(*)) as xs:integer
                   ) as xs:integer
             {if($n eq 0)
                 then 1
                 else $n * $f1($n -1, $f1)

              },
    $Fact := function($n as xs:integer) as xs:integer
            {
                $fact-base($n, $fact-base)
            }

   return
           $Fact(5)

One can run it with BaseX or with Oxygen, or directly online with BaseX
Fiddle: https://fiddle.basex.org/.
Using the same technique, one can also implement *mutual recursion* in pure
XPath 3:
https://dnovatchev.wordpress.com/2023/10/04/mutual-recursion-with-anonymous-inline-functions-in-xpath-3/

Here is the original blog article from 2012:
https://dnovatchev.wordpress.com/2012/10/15/recursion-with-anonymous-inline-functions-in-xpath-3-0-2/

Here is the paper at Balisage 2013:
https://www.balisage.net/Proceedings/vol10/html/Novatchev01/BalisageVol10-Novatchev01.html

In Xpath 4 there will be more convenient and direct ways to implement
recursion, such as using *methods *of a map:
https://qt4cg.org/specifications/xquery-40/xpath-40.html#id-methods

Thanks,
Dimitre.

On Sat, Mar 29, 2025 at 1:29 AM Mukul Gandhi <gandhi.mukul@gmail.com> wrote:

> Hi XSLT community group,
>    I 've following XSLT3 stylesheet:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>                          version="3.0">
>
>   <xsl:output method="xml" indent="yes"/>
>
>   <xsl:variable name="factorial" select="function($num) { if ($num eq
> 0) then 1 else ($num * $factorial($num - 1)) }"/>
>
>   <xsl:template match="/">
>       <result>
>           <answer>
>               <xsl:value-of select="$factorial(2)"/>
>          </answer>
>          <answer>
>              <xsl:value-of select="$factorial(3)"/>
>          </answer>
>         <answer>
>             <xsl:value-of select="$factorial(4)"/>
>         </answer>
>     </result>
>   </xsl:template>
>
> </xsl:stylesheet>
>
> Within this stylesheet, value of the variable "factorial" is an XPath
> 3.1 inline function definition that uses recursion. I think, that this
> stylsheet when run should produce an XSL transformation result as
> follows:
>
> <?xml version="1.0" encoding="UTF-8"?><result>
>    <answer>2</answer>
>    <answer>6</answer>
>    <answer>24</answer>
> </result>
>
> Saxon-HE 12.4 has issues running this stylesheet, and produces
> following XSL transformation result:
>
> Variable $factorial cannot be used within its own declaration
>
> Please take appropriate measures to solve an XSL transformation issue
> mentioned within this mail. I'm not sure, but probably an XSLT3 test
> case corresponding to this use case should be added to XSLT3 test
> suite.
>
>
> --
> Regards,
> Mukul Gandhi
>
>

Received on Saturday, 29 March 2025 14:39:23 UTC