faylang / fay

A proper subset of Haskell that compiles to JavaScript
https://github.com/faylang/fay/wiki
BSD 3-Clause "New" or "Revised" License
1.29k stars 86 forks source link

"Too much recursion" when using "when" instead of if #423

Closed ghost closed 9 years ago

ghost commented 9 years ago

The following code works (except that the first putStrLns are swallowed). However when I comment the "if" line and uncomment the "when" line I get a "too much recursion"-error and the program halts prematurely.

main :: Fay ()
main = do
    putStrLn "beg"
    loop
    putStrLn "end"
    where
        now :: Fay Double
        now = ffi "window.performance.now()"
        loop = do
            t <- now
            putStrLn . show . floor $ t
            if t < 500 then loop else return ()
--            when (t < 500) loop
bergmark commented 9 years ago

I haven't really touched the TCO code so I can't immediately tell why this is occurring but I know Fay is limited in when it can detect tail calls. That the if alternative works gives me hope that it's solvable at least, preferably in the optimizer instead of changing the implementation of when but either solution is fine.

I don't expect to be able to tackle this myself anytime soon so if you are willing to look into this I'd very much appreciate it!

ryachza commented 9 years ago

I don't believe this is resolvable via tail call elimination since when is declared as Bool -> Fay a -> Fay () making it equivalent to if t < 500 then loop >> return () else return () in this case.

Is updating when to Bool -> Fay () -> Fay () matching base an option? I presume it was declared the way it is to avoid the need for explicit void in some cases?

bergmark commented 9 years ago

Sorry for the late reply.

Good catch! I think this is simply a mistake, I don't want fay-base to differ from base unless necessary.

bergmark commented 9 years ago

This was fixed by #428