haskell-mode
haskell-mode copied to clipboard
Forked thread stops printing to stdout in haskell-interactive-mode.
Running a separate thread, which prints to stdout or stderr, works as expected directly in GHCI and in inf-haskell, but in haskell-interactive-mode it simply stops writing to stdout whenever nothing is waiting for it. Here is an example of the issue:
foo :: Int -> IO ()
foo 0 = return ()
foo n = do
putStrLn $ "Counting: " ++ show n
hFlush stdout -- just in case.
threadDelay 1000000
foo (n-1)
bar :: IO (IO ())
bar = async (foo 10) >>= (return . wait)
So, if I call bar, it just stops counting after the first iteration:
λ> g <- bar
Counting: 10
λ>
But if I start waiting for that thread a few seconds later it resumes printing to stdout.
λ> g
Counting: 6
Counting: 5
Counting: 4
Counting: 3
Counting: 2
Counting: 1
Very interesting, can you help debug this further?
I am not that familiar with Lisp in order to be of much help with this issue. But, here is something that looks related and might be useful. If you run infinitePrinter 2 in ghci, it will print 2 until it is killed with Ctrl-C. If you run runPrinter 3, it will start printing 3. Then hitting Ctrl-C will get you the prompt back, but printing will still continue. This behavior makes sense, because ghci didn't start that thread that does the printing, runPrinter did. Here is the actual code:
infinitePrinter n = do
putStrLn $ "Printing: " ++ show n
threadDelay 1000000
infinitePrinter n
runPrinter n = do
t <- async (infinitePrinter n)
wait t
But something very strange happens in haskell-interactive-mode, sending SIGINT, doesn't kill the second thread either, but it stops it from printing until you use the same function!?!?
λ> runPrinter 2
Printing: 2
Printing: 2
Interrupted.
λ> runPrinter 4
Printing: 4
Printing: 2
Printing: 4
Printing: 2
Interrupted.
λ> infinitePrinter 5
Printing: 5
Printing: 4
Printing: 2
Printing: 5
Printing: 4
Printing: 2
Printing: 5
Interrupted.
λ> print "Hello"
"Hello"
λ>
Possibly related, I was trying https://github.com/abarbu/matplotlib-haskell and it prints output from python in regular (terminal) ghci (stuff like λ> /tmp/xyz.py:23: UserWarning: Requested projection is different from … shows up when I start plotting) but when run from haskell-mode's repl in Emacs I don't see any of that output.
It'd be nice if this output wasn't suppressed, so it's easier to debug problems.