On Mon, Sep 07, 2009 at 07:26:26AM -0400, David Roundy wrote:
Hmm. After experimenting a bit more, I think I'm going to give up on this particular project. I don't see a way to introduce a new IO without duplicating most/all of base and jhc. And even if I were to do that, it doesn't look like the result would work with FFI without requiring users to manually wrap FFI calls into IO from Jhc.Prim.IO.
Yeah, it would be tricky. The best way I could think of would be to have multiple versions of just the jhc library, and link base against different versions of it. it doesn't help with the FFI issues though and would still have issues. I am always looking for ways to turn "compiler-magic" into things that can be expressed to jhc by the user, but IO is fairly ingrained at the moment.
I find the idea of writing the Haskell runtime in plain old Haskell, simply by wrapping a less featureful IO very appealing, albeit likely to be less efficient. But alas, it doesn't look pleasant trying to work this as an option into Jhc. btw, I've gotten my Haskell IO monad to do exceptions as well as concurrency... although of course it can't handle errors in pure code without some sort of help... but then, that's inevitable. All implemented without even unsafePerformIO or unsafeInterleaveIO... which are themselves still unimplemented, and probably won't be able to spawn threads until such time as I move the ThreadState into an IORef or something of the sort. But then, an unsafePerformIO that spawns a thread that outlasts its result is a pretty unholy beast.
Yes, those ideas are definitely appealing. I originally implemented exceptions directly in the IO monad, but found them to greatly clutter up the generated code for paths that were rarely used. I ended up thinking a middle ground would be in order, I didn't want to hardcode too much in a static C RTS, but implementing it directly in haskell seemed problematic, so I decided to include some appropriate Grin primitives and use those. Grin is a purely functional first order language, so it is still fairly easy to optimize, but it is close enough to what is actually run on the hardware that reasoning about things like exceptions and run-time cost is feasable. As for concurrency, I am leaning more towards a single pthread per haskell thread, however, doing things like blackholing would be exceedingly tricky in jhc, which raises the question of whether it actually is needed. Work may be repeated in theory, but I don't know if that will be an issue in practice. unsafePerformIO is more of an issue. Perhaps explicit locking can be used for those odd cases... In any case, I'd want it to be something that is relatively independent of the rest of the compiler, and can be turned on or off on a case-by-case basis. like how the garbage collector is fairly decoupled. John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/