
Hi. Since I discovered getExternalPrint, I found a ton of use cases for it. In particular, it makes it possible to write background threads that report stuff to the console without disturbing the prompt. I ended up writing a sort of uGHCi with the help of hint and the unreleased master branch of haskeline[1] to make externalPrint available from within the interpreter. Combined with Shh, this opens the door for a lot of useful functionality. Here is a simplified example based on shell programming with the help of Shh: % let watch r p = forkIO . forever $ printProc p >> readIORef r >>= OS.sleep % delay <- newIORef 10 % clock <- watch delay OS.date Sat Mar 2 21:32:28 CET 2019 Sat Mar 2 21:32:38 CET 2019 % writeIORef delay 5 Sat Mar 2 21:32:48 CET 2019 Sat Mar 2 21:32:53 CET 2019 Sat Mar 2 21:32:58 CET 2019 Sat Mar 2 21:33:03 CET 2019 % killThread clock printProc uses externalPrint from haskeline to print the output of a shell command to the console without disturbing the prompt. The OS module in this example simply exports all executables as haskell functions, thanks to the TH magic from Shh. I am relying on a pretty crude hack to make this work: (rFd, wFd) <- liftIO createPipe eprint <- getExternalPrint -- from haskeline liftIO . forkIO . forever $ do (s, bc) <- fdRead rFd 1024 eprint s -- ... -- define a function in the interpreter using hint runStmt $ "let externalPrint s = fdWrite (read " <> show (show wFd) <> ") s >> pure ()" This hack is basically the whole magic of my own hand-rolled uGHCi. I'd love to not reinvent the wheel there, and just be able to use standard GHCi to make use of externalPrint. Question is, would a similar thing be possible to implement in GHCi directly, and if so, what would be required to make this work? I am likely far too much a rooky to get this working on my own, so I am asking for help. What steps should I follow to eventually achieve my goal? I guess submitting a feature request would be a start. However, I want progress, so I am wondering: * The pipe trick is likely too hacky for GHCi. Are there any other portable alternatives for getting data from within the interpreter to the haskell process running it? * Or is there a way to serialize an IO action into the interpreter that I've missed? The problem here is the boundary between the process that runs the interpreter, and the interpreter itself. I am a bit whacky on terminology here, but as I see it, getExternalPrint returns a function that has internal state. So it isn't really possible to make such a function available from within the interpreter. Hence, the pipe hack above, which just sends the *argument* to externalPrint from the interpreter to the process running it. Any insights that might help me make that available in standard GHCi? I really think this is a pretty unique feature that would enable all sorts of interesting interactive code. [1] Haskeline < 0.8.0 doesn't allow to combine IntterpreterT from hint with InputT because of the way exceptions are done. The master branch of haskeline fixes that, so finally you can have a transformer stack that combines both, allowing for pretty simple interactive haskell interpreters with readline functionality. Thanks for that! -- CYa, ⡍⠁⠗⠊⠕