F# vs OCaml: Stack overflow

后端 未结 2 1591
情深已故
情深已故 2021-01-30 06:31

I recently found a presentation about F# for Python programmers, and after watching it, I decided to implement a solution to the \"ant puzzle\" on my own.

There is a

2条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-30 07:13

    Let me try to summarize the answer.

    There are 3 points to be made:

    • problem: stack overflow happens on a recursive function
    • it happens only under windows: on linux, for the proble size examined, it works
    • same (or similar) code in OCaml works
    • optimize+ compiler flag, for the proble size examined, works

    It is very common that a Stack Overflow exception is the result of a recursive vall. If the call is in tail position, the compiler may recognize it and apply tailcall optimization, therefore the recursive call(s) will not take up stack space. Tailcall optimization may happen in F#, in the CRL, or in both:

    CLR tail optimization1

    F# recursion (more general) 2

    F# tail calls 3

    The correct explanation for "fails on windows, not in linux" is, as other said, the default reserved stack space on the two OS. Or better, the reserved stack space used by the compilers under the two OSes. By default, VC++ reserves only 1MB of stack space. The CLR is (likely) compiled with VC++, so it has this limitation. Reserved stack space can be increased at compile time, but I'm not sure if it can be modified on compiled executables.

    EDIT: turns out that it can be done (see this blog post http://www.bluebytesoftware.com/blog/2006/07/04/ModifyingStackReserveAndCommitSizesOnExistingBinaries.aspx) I would not reccomend it, but in extreme situations at least it is possible.

    OCaml version may work because it was run under Linux. However, it would be interesting to test also the OCaml version under Windows. I know that the OCaml compiler is more aggressive at tail-call optimization than F#.. could it even extract a tail-recusable function from your original code?

    My guess about "--optimize+" is that it will still cause the code to recur, hence it will still fail under Windows, but will mitigate the problem by making the executable run faster.

    Finally, the definitive solution is to use tail recursion (by rewriting the code or by realying on aggressive compiler optimization); it is a good way to avoid stack overflow problem with recursive functions.

提交回复
热议问题