haskell-mode icon indicating copy to clipboard operation
haskell-mode copied to clipboard

Forked thread stops printing to stdout in haskell-interactive-mode.

Open lehins opened this issue 9 years ago • 3 comments

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

lehins avatar Oct 04 '16 21:10 lehins

Very interesting, can you help debug this further?

gracjan avatar Oct 08 '16 08:10 gracjan

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"
λ>   

lehins avatar Oct 12 '16 23:10 lehins

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.

unhammer avatar Dec 06 '21 10:12 unhammer