f(x) => s(x) if your termination condition is met (i.e. no more books)f(x) => f(g(x))
f(x) => s(x) if your termination condition is met (i.e. no more books)f(x) => something + f(g(x))
declare variable $bookstore := <bookstore>{for $i in 1 to 300000return element book {element name {"Book " || $i},element price {1},element author {"Author "|| $i}}}</bookstore>;(:~Rolling total of prices@param $prices, accumulates the book prices.$prices[$n] contains the sum of prices for $book[position() <= $n]@param $books sequence of books not yet added to $prices:)declare function local:sum($prices, $books){let $book := head($books) (: Get first book in sequence :)let $prices := if(count($prices) = 0) (: if empty, initialize prices with first price :)then ($book/price )else ( (: add the current rolling total to the list of rolling totals :)(: that’s the concatenation part :)$prices,element price { $prices[count($prices)] + $book/price })return (if(count($books) > 1) thenlocal:sum($prices, tail($books)) (: here's the tail call :)else $prices)};<prices>{local:sum((), $bookstore/book)}</prices>
- mark as tail call: local:sum(if(empty($prices_2)) then (hea...
Am 18.02.2019 um 19:12 schrieb Giuseppe G. A. Celano <celano@informatik.uni-leipzig.de>:Hi Jonathan,Thanks for that. However, it returns the same stack overflow error as the other script, when <book/> are 38000. Encreasing the JVM size does not help either.On Feb 18, 2019, at 4:51 PM, Jonathan Robie <jonathan.robie@gmail.com> wrote:To make it tail-recursive, make the recursive call the last operation in the function.The else() clause is what keeps it from being tail recursive. Something like this should work:declare variable $bookstore := <bookstore>
<book>
<name>story</name>
<price>50.00</price>
<author>smith</author>
</book>
<book>
<name>history</name>
<price>150.00</price>
<author>kelly</author>
</book>
<book>
<name>epic</name>
<price>300.00</price>
<author>jones</author>
</book>
</bookstore>;
declare function local:sum($books, $sum)
{
let $sum := $sum + $books[1]/price
return (
<price>{ $sum }</price>,
$books[2] ! local:sum(tail($books), $sum)
)
};
<prices>
{
local:sum($bookstore/book, 0)
}
</prices>JonathanOn Mon, Feb 18, 2019 at 10:24 AM Giuseppe G. A. Celano <celano@informatik.uni-leipzig.de> wrote:I am writing a recursive function which is similar to the one here:
https://stackoverflow.com/questions/27702718/to-add-values-in-cumulative-format
Interestingly, local:sum() works if there are not many <book/>. However with 38000 book element I get the error "Stack Overflow: Try tail recursion".
Any idea?
Ciao,
Giuseppe