Stack overflow with random-number-generator

Monday, 11 May 2020 · 3 messages · last reply 12 May 2020
MH
Martin Honnenin reply to Joe Wicentowski, 12 May 2020, 01:3311 May 2020 23:44 #
Quoted text · Joe Wicentowski · 5 lines
On 11.05.2020 23:33, Joe Wicentowski wrote: > I found a version that works. In the original version I must not have > been using tail recursion correctly. Here is the version that works. > Can anyone explain why the first version doesn't properly trigger tail > recursion?
No, but I think you can also apply fold-left
fold-left(
   1 to 2000,
   random-number-generator(),
   function($a, $i) { head($a)?next(), head($a)?number, tail($a) }
) => tail() => count()
instead of setting up your own tail recursive functions.
JW
Joe Wicentowski12 May 2020 01:20 #
Hi all, I encountered a stack overflow error with the following code, which is designed to return as many random numbers as the user requests. BaseX's error suggested, "Try tail recursion?" I think I am already using tail recursion. Changing the $n variable from 1407 to 1406 or lower avoids the error. Any number 1407 or higher triggers the error. Thank you for any hints! Joe
xquery version "3.1";

declare function local:get-random-numbers($how-many as xs:integer,
$generator as map(*)) {
    if ($how-many ge 1) then
        (
            $generator?number,
            local:get-random-numbers($how-many - 1, $generator?next())
        )
    else
        ()
};

declare function local:get-random-numbers($how-many as xs:integer) {
    local:get-random-numbers($how-many, random-number-generator())
};

let $n := 1407
return
    local:get-random-numbers($n) => count()
JW
Joe Wicentowski12 May 2020 01:33 #
I found a version that works. In the original version I must not have been using tail recursion correctly. Here is the version that works. Can anyone explain why the first version doesn't properly trigger tail recursion?
xquery version "3.1";

declare function local:get-random-numbers($how-many as xs:integer,
$generator as map(*), $accumulator) {
    if ($how-many ge 1) then
        local:get-random-numbers($how-many - 1, $generator?next(),
($accumulator, $generator?number))
    else
        $accumulator
};

declare function local:get-random-numbers($how-many as xs:integer) {
    local:get-random-numbers($how-many, random-number-generator(), ())
};

let $n := 2000
return
    local:get-random-numbers($n) => count()
Quoted text · Joe Wicentowski · 35 lines
On Mon, May 11, 2020 at 5:20 PM Joe Wicentowski <joewiz at gmail.com> wrote: > Hi all, > > I encountered a stack overflow error with the following code, which is > designed to return as many random numbers as the user requests. BaseX's > error suggested, "Try tail recursion?" I think I am already using tail > recursion. Changing the $n variable from 1407 to 1406 or lower avoids the > error. Any number 1407 or higher triggers the error. > > Thank you for any hints! > Joe > > ``` > xquery version "3.1"; > > declare function local:get-random-numbers($how-many as xs:integer, > $generator as map(*)) { > if ($how-many ge 1) then > ( > $generator?number, > local:get-random-numbers($how-many - 1, $generator?next()) > ) > else > () > }; > > declare function local:get-random-numbers($how-many as xs:integer) { > local:get-random-numbers($how-many, random-number-generator()) > }; > > let $n := 1407 > return > local:get-random-numbers($n) => count() > ``` >

⚡Generated with XQuery