valderman / haste-compiler

A GHC-based Haskell to JavaScript compiler
http://haste-lang.org
BSD 3-Clause "New" or "Revised" License
1.45k stars 109 forks source link

Tail call optimization fails on multidimensional iteration #408

Open pimlu opened 7 years ago

pimlu commented 7 years ago

I get some weird SO behavior on the following program, which I think Haste tries to avoid by policy to my understanding. (I tried simplifying the code in a few ways, but it wouldn't crash anymore.)

import Haste.Foreign
import Haste.Prim
import Data.Function

data Point = Point Double Double
sqdist (Point x y) = x^2 + y^2

calcpi n = fdiv (400*count) $ n^2
  where fdiv = (/) `on` fromIntegral
        count = length $ filter ((<=1) . sqdist) points
        points = [Point (fdiv j l) $ fdiv i l | i<-[0..l], j<-[0,100..l]]
        l = n-1

main = export (toJSStr "calcpi") calcpi

Note the use of [0,100..l] in the second loop - this is to crash faster, because the inner loop is TCO'd but the outer loop results in a few function calls each iteration. However, this only happens the second time it's evaluated:

stack trace on second call

If I expand the inner loop to [0..l], it will hang indefinitely if I call it with n=5000 first (it probably eventually returns); I would have to call it with lower values of n to successfully blow the stack.

I'm using the latest haste binary release (0.5.5.1). Built with -O2 --opt-all --pretty-print.