F# tail recursion stack overflows when not run locally -
F# tail recursion stack overflows when not run locally -
i having problems running below recursive function on our development web server. causes stack overflow. runs fine locally when in debugging mode. here things have tried:
made sure 'generate tail calls' enabled under build options. i ran disassembler , followed instructions here: http://blogs.msdn.com/b/fsharpteam/archive/2011/07/08/tail-calls-in-fsharp.aspx , not appear using tail recursion. i've tried rewriting without using recursion f# skills not best.so questions be:
is function going able utilize tail end recursions? why work locally in debugging mode through vs not on dev web server?thanks!
let rec simulationloop (rownum : int) (h : double) (time : double) (v : double) (s : double) (p : double) (newv' : double) (news' : double) (newp' : double) (designparameters : designparameters) (inputs : isimulationinputprovider) = seq { //let timer = system.diagnostics.stopwatch.startnew() allow finaltime = (6.0 * inputs.shockabsorber.stroke / designparameters.velocityafterimpact) allow starth = starth h time finaltime allow slopes = slopes v s p newv' news' newp' starth designparameters inputs allow vslope, sslope, pslope = slopes allow betalist = [ j in 0 .. 5 -> beta.[j].[4] ] allow newv' = calcprime v starth vslope betalist allow news' = calcprime s starth sslope betalist allow newp' = calcprime p starth pslope betalist allow delta = delta h slopes allow tau = tau v s p allow rowresult, rownum, time, newv, news, newp = if delta < tau recordresults rownum time starth v s p slopes designparameters inputs else none, (rownum + 1), time, v, s, p allow loop = news < inputs.shockabsorber.stroke - 0.01 && newv >= 0.0 && rownum <= 8000 && (time < finaltime && time + h > time) allow steplength = strokesteplength inputs.shockabsorber.stroke designparameters.holesize allow endh = endh delta starth tau steplength newv //timer.stop() //system.diagnostics.debug.writeline("row: " + rownum.tostring() + " = " + timer.elapsedmilliseconds.tostring()) match (rowresult, loop) | row(r), true -> yield r yield! simulationloop rownum endh time newv news newp newv' news' newp' designparameters inputs | row(r), false -> yield r | none, true -> yield! simulationloop rownum endh time newv news newp newv' news' newp' designparameters inputs | none, false -> () }
because body of function sequence expression, compiler doesn't utilize tail recursion. however, simply calling simulationloop
should not cause stack overflow since should generate sequence without evaluating contents. furthermore, given nature of code, expect state machine compiler generates stepping through sequence run without overflowing stack well.
how using result of calling simulationloop
when see error? platforms local , web machines (e.g. both 32-bit)? if trim downwards illustration (e.g. removing calls calcprime
, recordresults
, etc.) see same behavior?
f# tail-recursion
Comments
Post a Comment