On Dec 10, 2007, at 15:27, Richard Jones wrote: > On Mon, Dec 10, 2007 at 05:33:21PM +0100, Oliver Bandel wrote: > >> Zitat von Fabrice Pardo : >> >>> When using these kind of external C functions, OCaml seems then >>> less comfortable to the programmer than reference counted languages. >> >> I doubt that reference-count is the reason here. perl also uses >> reference count, but Filehandles and Dirhandles have to be closed >> with close / closedir. > > This isn't true. In Perl file handles are closed at the end of a > scope if they are no longer used. In other words a Perl-equivalent > to this loop will never use more than a single file descriptor: > > while (true) { > open "foo" > } > > Even in a GC'd language which could finalize the file handle you > could never be sure when the GC is going to be called so it could > use an indefinite number of file descriptors. > > There is a really good paper on this subject -- how ref counting and > garbage collection are orthogonal language concepts -- but I can't > find it right now. True. To address the original point, however: This is a significant problem that crops up frequently in language/ runtime designs, especially when migrating to static, garbage collected runtimes from scripting runtimes. parrot tackled this problem; they call it timely collection and went far out of their way to implement it, performing miniature collections when a resource variable goes out of scope. This is rather expensive. The practical reality is that, short of re-engineering memory management, developers migrating from C++ (RTTI) and scripting languages may need to retrain themselves to recognize that: finalization does not provide a time bound on destruction garbage collection manages memory and no other resources C# provides a convenient using construct to ease the pain, but Java code is littered with finally blocks for this reason. Ocaml is hampered in that its try block has no native finally construct, which requires repetition in the normal flow-of-control and exceptional cases. Implementing reusable using constructs with filters and closures for each type of resource is the best option I've seen, although a generic finally construct is also possible also using closures: let finally expr cleanup = try let result = expr () in cleanup (); result with x -> cleanup (); raise x Unfortunately, this is not at all attractive at the call site. — Gordon