
Conal Elliott wrote:
I'm puzzled why explicit bracketing is seen as an acceptable solution. It seems to me that bracketing has the same drawbacks as explicit memory management, namely that it sometimes retains the resource (e.g., memory or file descriptor) longer than necessary (resource leak) and sometimes not long enough (potentially disastrous programmer error). Whether the resource is system RAM, file descriptors, video memory, fonts, brushes, bitmaps, graphics contexts, 3D polygon meshes, or whatever, I'd like GC to track the resource use and free unused resources correctly and efficiently.
The lifetime problems are worse without explicit bracketing IMHO: One has to wait for the next GC to free them (resource leaks) and even without bracketing there's nothing to stop you from using a Handle after closing. Furthermore, the main difference between simple RAM and more "external things" like Handles is that the effect of keeping them occupied is observable from outside our happy Haskell world, e.g. a server socket might stay open, taking away a port number, an external device with exclusive access is unusable until the next GC, my valuable texture memory on the graphics card contains unused textures until the GC runs, etc. etc. Finalizers are not a solution for these problems, a fact that e.g. a lot of novice Java programmers have to learn when they do their first "real world" programs... IMHO it would be best to use explicit bracketing where possible, and hope for the RTS/GC to try its best when one runs out of a given resource. Admittedly the current Haskell implementations could be improved a little bit in the last respect. Cheers, S.