section 5.5:
It's going to be really hard to implement ForeignPtr as specified. The problem is that invocation of the cleanup function is triggered by the garbage collector. I don't want the garbage collector to be recursively invoked so I don't want the garbage collector to directly invoke Haskell function. The Hugs garbage collector is not supposed to be a mutator of the heap - so putting a simple wrapper round the garbage colector won't work. And there's no mechanism outside the GC to look for cleanup functions to execute.
GHC gets round this by scheduling a (preemptive) thread to execute the cleanup code. How on earth does NHC get round this? Does anyone have a suggestion for how it might be implemented in Hugs?
Proposed change: none at present but I'm deeply sceptical of a design which takes a simple task (invoke a C cleanup function) and, for no discernable reason, generalizes it to the point that it requires a much more complex runtime system.
I've attached some mail I dug up on the subject, from before the creation of ffi@haskell.org (there's more in the archives of that list). The upshot is: - Haskell finalizers are much more in keeping with the general philosophy of the FFI: do as much in Haskell as possible. It looks a bit strange if you have to do your allocation in Haskell but deallocation in C. - If we forced finalizers to be C functions because calling Haskell from the GC is inconvenient, then you have to add a constraint that the C function invoked from a finalizer can't call any functions foreign-exported from Haskell land. That's an annoying constraint to have to add, because it means that C libraries can't be transparent w.r.t. whether they invoke Haskell code or not (actually the hs_init() problem that someone else brought up recently also has this side-effect). Malcolm can comment on exactly how nhc98 handles the finalizers, but I believe that there's a list of pending finalizers maintained by the RTS which are run on re-entry to Haskell land. The equivalent would be to add a check in Hugs's eval loop, I imagine.
Table 2 (section 6):
Is there a reason to be so coy about the concrete C types used for HsChar, HsFloat, HsDouble and HsBool?
Proposed change:
C symbol Haskell Symbol Constraint on concrete C type HsChar Char unsigned char
HsChar is an unsigned 32-bit int in GHC. We probably ought to say that the type is unsigned, at least - and the Haskell 98 standard requires that it can at least contain all the Unicode character values (20 bits?). Cheers, Simon