I have just read Hans Boehm's POPL paper on finalizers. His suggestion for the use of finalizers in single-threaded systems is to provide a `runFinalizers' routine, instead of relying on the asynchronous execution that, as established, requires support for concurrency. I am not sure whether we have given this option really serious consideration. Why may this option be interesting? It may allow us to have Haskell finalizers after all. As Boehm explains, ``finalizers generally fall into two categories: Those that simply deallocate operating system resources and those that touch other user data structures.'' It seems that we currently, probably due to our FFI bias, concentrate on the former kind. The main benefit of Haskell finalizers, apart from convenience, is the ability to process Haskell structures. As I understand Boehm, we might adopt the following design: * Finalizers are normal Haskell routines. * When the GC discovers that a finalizer becomes enabled, it is added into a list of enabled finalizers (but not run in a single-threaded system). * When the routine runFinalizers :: IO () is called, it runs the finalizers in the list of enabled finalizers one after the other. * Systems supporting pre-emptive concurrency *may* run finalizers at any time after they become enabled, but they must run them when `runFinalizers' is called (similar to `performGC'). An attractive property of this design is that it provides a smooth transition from single-threaded systems to systems providing pre-emptive concurrency. The requirement to invoke `runFinalizers' explicitly might not be too burdensome in practice as code making heavy use of the FFI and finalizers probably spends a lot of time in the IO monad with the opportunity to insert calls to `runFinalizers'. Opinions? Cheers, Manuel PS: Sorry for bringing finalizers up again, but if there is an opportunity to improve the current design, I think, we should consider it.
I have just read Hans Boehm's POPL paper on finalizers. His suggestion for the use of finalizers in single-threaded systems is to provide a `runFinalizers' routine, instead of relying on the asynchronous execution that, as established, requires support for concurrency.
I think there Haskell's laziness and, to a lesser extent, focus on side-effect free evaluation, makes a significant difference to the design landscape so what is appropriate in the languages Hans Boehm has experience of is less suitable for Haskell. In particular, strict imperative languages lend themselves to operational reasoning whereas Haskell's evaluation order can baffle even the experts and writing code with _portable_ operational behaviour is, I think, impossible with current techniques and tools. This is exacerbated by the Haskell report which deliberately avoids the subject and the range of different optimizations implemented by different compilers. -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
participants (2)
-
Alastair Reid -
Manuel M T Chakravarty