A non-tail recursive function does not explode in GHCi. What for?

I expected to see my hit on the stack with the following code .. but he did not:

*Main> let blowwss x = if x == 0 then 0 else (1 + blowwss (x-1)) *Main> blowwss 1000000 1000000 

The function does not seem to be tail recursive, so I wonder what I might lose. Is the GHCi stack bigger than I thought (how can I see its stack size, by the way?). Does any springboard use to overcome this? Is he smart enough to convert a function to its iterative instance?

thanks

+5
source share
2 answers

The GHCi stack is bigger than you think. IIRC, the default stack size for the compiled program is 500M for GHCi, while the default stack size for the compiled program is currently 8M. You can set a smaller limit yourself to see that you get a stack overflow (or you can significantly increase your argument).

 $ ghci +RTS -K1M GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> let blowwss x = if x == 0 then 0 else (1 + blowwss (x-1)) Prelude> blowwss 1000000 *** Exception: stack overflow 

Note that the GHC has a stack size limit solely to prevent endless / unexpectedly deep loops in situations that are most likely programming errors. In principle, the stack can grow indefinitely (constrained by system memory, of course). Even if you specify a large stack size, the stack actually starts much smaller, but can grow to the limit. There is currently a debate on the possibility of completely eliminating the limit in future versions of the GHC.

+7
source

You used a value too small for this. I moved your function to a separate file

 blowwss x = if x == 0 then 0 else (1 + blowwss (x-1)) main = do print $ blowwss 10000000000 print $ blowwss 10000000000000 

and then compiled and launched

 [ mihai@esgaroth tmp]$ ghc --make 1.hs [1 of 1] Compiling Main ( 1.hs, 1.o ) Linking 1 ... [ mihai@esgaroth tmp]$ ./1 Stack space overflow: current size 8388608 bytes. Use `+RTS -Ksize -RTS' to increase it. 

Running this in GHCI I get a high load and then a stack overflow. This is because the GHCi stack is higher, I think, somewhere around 512M.

+1
source

Source: https://habr.com/ru/post/959127/


All Articles