ghci and ghc -threaded broken with pipes & forking

Jeremy Shaw at
Thu Mar 1 14:04:09 EST 2007

At Thu, 1 Mar 2007 11:38:54 -0600,
John Goerzen wrote:
> On Thu, Mar 01, 2007 at 04:21:45PM +0000, Simon Marlow wrote:
> > >Between that and the lack of support for forkProcess in Hugs, this
> > >renders anything that needs to fork and then do I/O as being usable only
> > >in GHC-compiled code.  Which is sub-optimal, but livable anyway.
> > 
> > I guess I'm really wondering why you need to fork and do I/O at all.  Can 
> > you describe the problem at a higher level?
> I am, for all intents and purposes, writing what amounts to a simple
> shell.

The neat thing about the library is that external commands and haskell
code can be freely intermixed, and are uniformly handled.

For example, in this pipeline,

          r <- runS ("ls -l" -|-  "grep i" -|-  wcL  )

wcL is a simple haskell function:

wcL :: [String] -> [String]
wcL inp = [show $ genericLength inp]

The HSH library just creates some pipes to hook the processes
together, and then forks of ls, grep, and wcL as seperate processes.

The advantage of this scheme is that once the pipeline is started,
everything behaves the same way it would if you had run the bash

 $ ls -l | grep i | wcL

So, you get very familiar behaviour/performance from a shell scripting
point of view. But, you also get to easily stick haskell functions in
your pipeline.

Poking around with the full HSH code, I *think* I got pipelines that
*only* called external commands working fine[1]. This seems logical,
since the external commands do not care about the Haskell I/O manager
at all.

So, perhaps you can have an alternate version of 'instance
ShellCommand (String -> IO String)' that gets used for -threaded that
uses forkOS instead of forkProcess. All of the external commands would
still be forked into seperate processes, but all of the haskell
commands would run in the same threaded process. Obviously, you would
have to fake the return code, but it looks like that should be

Some open questions are:

 a) how do you detect that you are running in the threaded RTS

 b) can you have the linker pick the correct version at link time, so
    that you do not have to have a compile-time check. Of course, a
    compile time check might only have to be done once, so the
    overhead would not be significant.


[1] In fact, they may work fine out of the box, I haven't tested that.

More information about the Glasgow-haskell-users mailing list