From: Michael Kay <mike@sa...>  20130206 22:32:28

I have added this to the XSLT 3.0 test suite as test case higherorderfunctions068, and I confirm it is still failing with the current development build. The hypothesis I am exploring is that it is an interaction between function closures and tail recursion; my suspicion is that when the stackframe is reused/overwritten for the purpose of tailrecursion, the values required for the function closure are being corrupted. It's all pretty complex! Michael Kay Saxonica On 06/02/2013 03:14, Abel Braaksma wrote: > When I define the following continuation version of the Fibonacci > sequencein XSLT 3: > > <xsl:function name="f:fib"> > <xsl:param name="n" as="xs:integer" /> > <xsl:param name="countfun" as="function(*)" /> > > <xsl:sequence select=" > if ($n = 1 or $n = 2) > then $countfun(1) > else let $first := > function($x as xs:integer) as function(*) > { > let $second := function($y as xs:integer) as > function(*) > { > $countfun($x + $y) > } > return f:fib($n  2, $second) > } > return f:fib($n  1, $first)" /> > </xsl:function> > > and I call it as follows: > > <xsl:valueof select="f:fib(10, function($a as xs:integer){$a})" /> > > the expected result is 55. However, I receive the following error: > > Engine name: SaxonEE 9.4.0.4 > Severity: fatal > Description: Required item type of second argument of anonymous > function is function(); supplied value has item type xs:integer > Start location: 36:0 > URL: http://www.w3.org/TR/xslt20/#errXTTE0790 > > The function is inspired by this snippet http://fssnip.net/eU, though > other functional languages have similar examples. The idea behind the > excercise is to eliminate the double recursive exit pointof the > function by creating a continuation function. However, either the > error is confusing(I don't see any anonymous function call with > afunction argument) or something else is happening. > > I also tried the fully typed version, and an untyped version. Here's > the fully typed variant: > > <xsl:function name="f:fib" as="xs:integer"> > <xsl:param name="n" as="xs:integer" /> > <xsl:param name="countfun" as="function(xs:integer) as xs:integer" /> > > <xsl:sequence select=" > if ($n = 1 or $n = 2) > then $countfun(1) > else let $first := > function($x as xs:integer) as xs:integer > { > let $second := function($y as xs:integer) as > xs:integer > { > $countfun($x + $y) > } > return f:fib($n  2, $second) > } > return f:fib($n  1, $first)" /> > </xsl:function> > > > Any idea what I'm missing here, or is this perhaps an error with Saxon? > > Thanks, > Abel > > > > >  > Free NextGen Firewall Hardware Offer > Buy your Sophos nextgen firewall before the end March 2013 > and get the hardware for free! Learn more. > http://p.sf.net/sfu/sophosd2dfeb > > > _______________________________________________ > saxonhelp mailing list archived at http://saxon.markmail.org/ > saxonhelp@... > https://lists.sourceforge.net/lists/listinfo/saxonhelp 